Şu anda görüntülenen parçayı nasıl edinebilirim?


445

Android'de parçalarla oynuyorum.

Aşağıdaki kodu kullanarak bir parçasını değiştirebileceğini biliyorum:

FragmentManager fragMgr = getSupportFragmentManager();
FragmentTransaction fragTrans = fragMgr.beginTransaction();

MyFragment myFragment = new MyFragment(); //my custom fragment

fragTrans.replace(android.R.id.content, myFragment);
fragTrans.addToBackStack(null);
fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragTrans.commit();

Benim sorum, bir Java dosyasında, şu anda görüntülenen Fragment örneğini nasıl alabilirim?



Yanıtlar:


454

Parçayı işleminize eklediğinizde bir etiket kullanmalısınız.

fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT");

... ve daha sonra parçanın görünür olup olmadığını kontrol etmek istiyorsanız:

MyFragment myFragment = (MyFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT");
if (myFragment != null && myFragment.isVisible()) {
   // add your code here
}

Ayrıca bkz. Http://developer.android.com/reference/android/app/Fragment.html


74
Tamam, ama şu anda görüntülenen Fragment örneğini hemen almanın bir yoluna ihtiyacım var, tekrarlı olarak tüm fragmanları kontrol edip ekranda hangi parçanın görüntülendiğine karar vermiyorum. Sanırım cevabın her bir
parçamı

33
Evet, ama aynı anda birden fazla parça görülebilir. Yani "sadece aktif parça" gibi bir şey yok ....
ramdroid

6
Tamam, görüntülenen birkaç parça olsa bile, hala onları elde etmenin bir yoluna ihtiyacım var ... ve her bir parçamı tekrar tekrar kontrol etmekten daha iyi bir yola ihtiyacım var. "GetDisplayedFragment () gibi bir yöntem" olsun "endişe duyuyorum, ancak Android
Leem.fin 15:12

2
Bunun sizin için neden bir sorun olduğunu bilmiyorum ... Bir aktivitede genellikle sadece birkaç parçanız vardır ve görünür olup olmadıklarını kontrol etmek gerçekten sorun olmamalıdır.
ramdroid

12
Neden herkes bu cevabı destekliyor? Tabii, güzel bir kod biraz ama etikete göre belirli bir parçayı almak için soruyu cevaplamıyor. AMA Asker şu anda görüntülenen parçayı istiyor, yani hangi parçanın görüntülendiğini bilmiyor. Evet, birden fazla parça olabilir, ancak soruyu okumak kullanıcı arayüzünde yalnızca 1 parçayı gösterir. Üzgünüm soru bağlamını cevaplamadığı için aşağı indirmek zorunda kaldı.
angryITguy

410

Eski bir yazı olduğunu biliyorum, ama daha önce de sorun yaşıyordum. Bunu onBackStackChanged()dinleme fonksiyonunda yapacak bir çözüm buldum

  @Override
    public void onBackPressed() {
        super.onBackPressed();

         Fragment f = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
      if(f instanceof CustomFragmentClass) 
        // do something with f
        ((CustomFragmentClass) f).doSomething();

    }

Görünür olanı bulmak zorunda olduğum her parçayı tekrarlamak istemediğim için bu benim için çalıştı. Umarım başka birine de yardımcı olur.


13
Bir Gezinme Çekmece ile ekran döndürme sonra onBackPressed () ile uğraşırken tam olarak ne aradığını. Bunu paylaşmak için geri geldiğin için teşekkürler.
ShortFuse

1
FindFragmentById dahili olarak tüm parçaları yinelemiyor mu? :)
Andrew Senner

46
bu durumda .getFragmentManageruyumsuz türünü bildirir o benim durumumda olduğu gibi ben kullanıyordum çünkü, öyle android.support.app.v4.Fragmentkullanımına doğru bir yöntemdir, bu durumda,getSupportFragmentManager
Răzvan Barbu

3
ya kullanabilirsiniz findFragmentByTag()yerine findFragmentByIdonu eklerken parçasına etiketi sağlanan varsa,fragmentManager.beginTransaction() .add(containerID, frag, fragmentTag) .addToBackStack(fragmentTag) .commit();
DeltaCap019

@AndrewSenner, açıkça yapmak istemediği anlamına geliyor :)
Farid

161

İşte düşük parçalı senaryolar için kullanışlı bulduğum çözümüm

public Fragment getVisibleFragment(){
    FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    if(fragments != null){
        for(Fragment fragment : fragments){
            if(fragment != null && fragment.isVisible())
                return fragment;
        }
    }
    return null;
}

13
fragmentarka yığını açtığınızda olduğu gibi belirli senaryolarda boş olabilir. Çok daha iyi kullanın if (fragment != null && fragment.isVisible()).
cprcrack

8
yöntem eksik çünkü sadece bir parça görünür değil
letroll

Hiçbir parça görünür değilse, fragmentManager.getFragments (), NULL sonucunu döndürerek NPE'ye "NULL nesne başvurusunda 'java.util.Iterator java.util.List.iterator ()' arabirim yöntemini çağırmayı dener" diyecektir. Bu nedenle, for döngüsü basit bir kontrolle çevrelenmelidir: if (fragman! = Null)
Pranav Mahajan

Birden fazla parça görünürse ne olur?
Shivaraj Patil

5
Teknik olarak bu soruya göre cevap olarak işaretlenmelidir. Asker, hangi parçanın olduğunu bilmeden, şu anda görüntülenen parçayı istiyor. Diğer yanıtlar etikete göre fragman almaya devam ediyor
angryITguy

76

Her fragman gösterdiğinizde etiketi backstack'e koymalısınız:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK);       
ft.add(R.id.primaryLayout, fragment, tag);
ft.addToBackStack(tag);
ft.commit();        

Ve sonra mevcut parçayı almanız gerektiğinde bu yöntemi kullanabilirsiniz:

public BaseFragment getActiveFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return (BaseFragment) getSupportFragmentManager().findFragmentByTag(tag);
}

4
Bu tekniğin, bir ViewPager ile kullanılan Parçalar için çalışmayacağından eminim, çünkü bunlar etikete eklenmedi. Sadece oraya atarak.
loeschg

3
Bu sadece aradığınızda işe yarıyor gibi görünüyor addToBackStack(tag), ama parçayı arka yığına eklemek istemezseniz ne olur?
cprcrack

1
Bu, yalnızca etiketiniz arka yığın adıyla aynı olduğunda çalışır ve bu alışılmadık gibi görünür.

Aynı işleme 5 parça eklediyseniz ne olur?
Kevin Lam

Bir ada ihtiyacınız olmayan bazı Parçalar için addToBackStack (null) çağırırsanız getName () yönteminin null döndürdüğünü ve bir NPE aldığını söylemek güzel olabilir. @ dpk, docu diyor ki: Bu girişi oluştururken FragmentTransaction.addToBackStack (String) öğesine sağlanan adı alın. Ayrıca, EntryCount 0 olup olmadığını ve bir üst girdi almaya çalışın bir null denetim ekleyin.
JacksOnF1re

23

Geçerli görüntüleme parçası bulmak için kullanıyorum ne kodu altında. Çok basit ve şimdiye kadar benim için çalışıyor. Parçaları tutan aktivitede çalışır

    FragmentManager fragManager = this.getSupportFragmentManager();
    int count = this.getSupportFragmentManager().getBackStackEntryCount();
    Fragment frag = fragManager.getFragments().get(count>0?count-1:count);

3
Get (count-1) bir IndexOutofBoundsException oluşturmuyorsa, count> 0 değerinden emin olmalısınız
kehers

@tainy bu değiştirilen ama backstack eklenmemiş parçası vermeyecektir. Evetse, tag argümanını kullanarak alabilir miyim?
cafebabe1991

GetFragments çağrısı, parçalara popBackStack'ı (null, FragmentManager.POP_BACK_STACK_INCLUSIVE) çağırdıktan sonra daha fazla parça ekledikten sonra parçalara eklendikleri sırayı vermeyecektir.
LEHO

etkinliğin birden fazla Parçası görünürse, yolunuz yanlıştır. Örneğin: Parçalarla ViewPager. bildiğim gibi getBackStackEntryCount () işlem sayısını değil, parça sayısını değil
HungNM2

Sen kontrol etmelisiniz fragManager.getFragments().size()yerine getBackStackEntryCount()onlar (benim durumda olan) mutlaka eşit değildir olarak. Aksi takdirde IndexOutOfBoundsException
RustamG

19

Kotlin yolu;

val currentFragment = supportFragmentManager.fragments.last()

Yalnızca API 26 ve sonraki
sürümlerde çalışır

1
@ibit Yalnızca API 26 ve sonraki sürümlerde çalışanlarla ne demek istiyorsun? Emulator API 19'un iyi çalışmasını denedim.
HendraWD

@HendraWD haklısın! getFragments()API 26 ve üstü olan frameworks fonksiyonundaki fonksiyondan bahsediyordum .
ibit

2
Kendine iyi bak. Eğer herhangi bir parça yığını yoksa, boş istisna neden olabilir!
Jetwiz

Bu işe yaramıyor mu? java.lang.ClassCastException: androidx.navigation.fragment.NavHostFragment Fragment için kullanılamaz
coolcool1994

13

Reaktif bir şekilde:

Observable.from(getSupportFragmentManager().getFragments())
    .filter(fragment -> fragment.isVisible())
    .subscribe(fragment1 -> {
        // Do something with it
    }, throwable1 -> {
        // 
    });

7
bu nasıl reaktif? Gözlenebilir bir şey kullanırsınız, ancak yalnızca bir kez
Tim

6
Ve bu sadece aşırıya kaçma. Basit bir gelişmiş forloop da aynı şeyi yapar, belki daha da hızlıdır.
Peterstev Uremgba

sadece akış api için reaktif akışı kullanmak o kadar akıllı değil, aslında listeyi bir akış olarak ele almak ve api filtresini uygulamak istiyorsanız aşırı bir Java9 api buharını kullanın dediler
AndroidLover

13

Benim yöntem denemek / yakalamak böyle dayanmaktadır:

MyFragment viewer = null;
    if(getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT) instanceOf MyFragment){
    viewer = (MyFragment) getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT);
}

Ama daha iyi bir yol olabilir ...


1
Benim sorum şu anda görüntülenen fragman nasıl elde edilir, yani çok sayıda fragman olabilir, sadece şu anda görüntülenen bir örneğini almak istiyorum, neden (MyFragment) kullanın ?? Demek istediğim, ekranda herhangi bir Fragment ekranı olabilir ... ve şu anda görüntülenen parçayı almak istiyorum.
Leem.fin

MY_TAG_FRAGMENT bir değiştirme kullanmadan önce oluşturduğum parçanın etiketi, şunun gibi: fragmentTransaction.replace (R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT);
Thordax

Birden fazla parçam varsa, .replace (...) öğesini çağırırken tüm parçalar için bir etiket kullanabilir miyim?
Leem.fin

Evet, sorun değil, şu kodu kullanın: fragmentTransaction.replace (R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT); ve iyi gidebilir.
Thordax

1
Peki, gerçekten anlamıyorum, şu anda görüntülenen Fragment örneğini hemen almak için bir yola ihtiyacım var, tüm parçaları tekrar tekrar kontrol etmeyin ve sonra ekranda hangi parçanın görüntülendiğine karar verin.
Leem.fin

11

Peki, bu soru çok sayıda görüş ve ilgi aldı, ancak yine de getFragments () kullanmak için sonumdan en kolay çözümü içermiyordu.

            List fragments = getSupportFragmentManager().getFragments();
            mCurrentFragment = fragments.get(fragments.size() - 1);

1
Ne yazık ki, bu her zaman doğru değildir getSupportFragmentManager().getFragments() , size bir liste verir, ancak en son parça backstack'ten attıysa, null değerleri tutabilir. Eq: Eğer yöntem içinde yolunuzu kontrol onBackStackChanged()ve bir popBackStack()yere çağırırsanız , o zaman mCurrentFragmentolacak null.
Stumi

@Stumi Bu bilgi için teşekkürler. Evet, Android'deki birçok garip yaşam döngüsü probleminden biri gibi geliyor.
Nativ

9

Hangi parçanın Etkinlikler içerik çerçevenize yüklendiğini sorgulayabilir ve parça sınıfını veya 'basit ad' parçasını (dize olarak) alabilirsiniz.

public String getCurrentFragment(){
     return activity.getSupportFragmentManager().findFragmentById(R.id.content_frame).getClass().getSimpleName();
}

Kullanımı:

Log.d(TAG, getCurrentFragment());

Çıktılar:

D/MainActivity: FragOne

8

Biraz geç oldu, ama ilgilenen herkes için: FragmentManager'da istediğiniz parçanın dizinini biliyorsanız, sadece bir referans alın ve isMenuVisible () işlevini kontrol edin! buraya :

getSupportFragmentManager().getFragments().get(0).isMenuVisible()

Eğer trueonun görünür kullanıcıya vb!


1
Garip bir şekilde, burada listelenen benim için çalışan tek çözüm buydu. Aynı zamanda, birden fragmanları olabilir isVisible() == true, getView() != null. Artı, benim kodumda getBackStackEntryCounther zaman sıfırdır. Ben menüleri kullanmama rağmen isMenuVisible(), şimdiye kadar 'aktif' parçası güvenilir bir şekilde işaret gibi görünüyor tek ayrımcı. ty
parvus

7

1)

ft.replace(R.id.content_frame, fragment, **tag**).commit();

2)

FragmentManager fragmentManager = getSupportFragmentManager();
Fragment currentFragment = fragmentManager.findFragmentById(R.id.content_frame);

3)

if (currentFragment.getTag().equals(**"Fragment_Main"**))
{
 //Do something
}
else
if (currentFragment.getTag().equals(**"Fragment_DM"**))
{
//Do something
}

6

Buraya gel ve Kotlin kullanıyorsanız :

var fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)

R.id.fragment_containerolduğu idyerde fragmentüzerinde sunuyor onlarınactivity

Veya daha güzel bir çözüm istiyorsanız:

supportFragmentManager.findFragmentById(R.id.content_main)?.let {
    // the fragment exists

    if (it is FooFragment) {
        // The presented fragment is FooFragment type
    }
}

5

Tainy'nin cevabından esinlenerek , işte iki sentim . Diğer uygulamaların çoğunda çok az değişiklik yapılmıştır.

private Fragment getCurrentFragment() {
    FragmentManager fragmentManager = myActivity.getSupportFragmentManager();
    int stackCount = fragmentManager.getBackStackEntryCount();
    if( fragmentManager.getFragments() != null ) return fragmentManager.getFragments().get( stackCount > 0 ? stackCount-1 : stackCount );
    else return null;
}

"myActivity"Geçerli etkinliğinizse "this" ile değiştirin veya etkinliğinize referans kullanın.


5

Denilen bir yöntem var findFragmentById()içinde SupportFragmentManager. Etkinlik kapsayıcısında şöyle kullanıyorum:

public Fragment currentFragment(){
    return getSupportFragmentManager().findFragmentById(R.id.activity_newsfeed_frame);
}

Akımınızı bu şekilde elde edebilirsiniz Fragment. Özel varsa Fragmentve ne Fragmentolduğunu kontrol etmeniz gerekiyorsa , normalde şunu kullanırım instanceof:

if (currentFragment() instanceof MyFrag){
    // Do something here
}


4

Mevcut parçayı almanın basit yolu budur ..

getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
  @Override public void onBackStackChanged() {
    currentFragment = fragmentManager.findFragmentById(R.id.content);
    if (currentFragment !=  null && (currentFragment instanceof LoginScreenFragment)) {
      logout.setVisibility(View.GONE);
    } else {
      logout.setVisibility(View.VISIBLE);
    }
  }
});

4

Sev'in cevabıSev'in , geri düğmesine bastığınızda veya başka bir şekilde backstack'i değiştirdiğinizde işe yarar.

Yine de biraz farklı bir şey yaptım. Bir baz parçası ve onun türetilmiş parçaları üzerinde backstack değişiklik dinleyici kurulum var ve bu kod dinleyicide:

Fragment f = getActivity().getSupportFragmentManager().findFragmentById(R.id.container);

if (f.getClass().equals(getClass())) {
    // On back button, or popBackStack(),
    // the fragment that's becoming visible executes here,
    // but not the one being popped, or others on the back stack

    // So, for my case, I can change action bar bg color per fragment
}

3

Bu benim için bir iş. Umarım bu birini çalacaktır.

FragmentManager fragmentManager = this.getSupportFragmentManager();  
        String tag = fragmentManager
                    .getBackStackEntryAt(
                    fragmentManager
                    .getBackStackEntryCount() - 1)
                    .getName();
              Log.d("This is your Top Fragment name: ", ""+tag);

3

Parçanın şu anki Fragment örneğini alıyorsanız,

findFragmentByID(R.id.container);

Bu aslında görünümde doldurulmuş parçanın şu anki örneği. Aynı sorunu yaşadım. Aynı parçayı iki kez backstack üzerinde tutmak zorunda kaldım.

Aşağıdaki yöntem işe yaramıyor. Sadece etiketi olan bir Parçayı alır. Bu yöntemle zaman kaybetmeyin. Kullanımları olduğundan eminim ama aynı Fragment'ın en son sürümünü almak bunlardan biri değil.

findFragmentByTag()

3

Bu çözümü inceleyin. Geçerli Parçayı almak benim için çalıştı.

if(getSupportFragmentManager().getBackStackEntryCount() > 0){
        android.support.v4.app.Fragment f = 
         getSupportFragmentManager().findFragmentById(R.id.fragment_container);
        if(f instanceof ProfileFragment){
            Log.d(TAG, "Profile Fragment");
        }else if(f instanceof SavedLocationsFragment){
            Log.d(TAG, "SavedLocations Fragment");
        }else if(f instanceof AddLocationFragment){
            Log.d(TAG, "Add Locations Fragment");
        }

2
final FragmentManager fm=this.getSupportFragmentManager();
final Fragment fragment=fm.findFragmentByTag("MY_FRAGMENT");

if(fragment != null && fragment.isVisible()){
      Log.i("TAG","my fragment is visible");
}
else{
      Log.i("TAG","my fragment is not visible");
}

Bu Jetpack ile çalışır?
IgorGanapolsky

2
getSupportFragmentManager().findFragmentById(R.id.content_frame).getClass().getSimpleName();

Sanırım bu soruya verilecek en basit cevap bu. Umarım bu yardımcı olur.


2

İşte bir Kotlin çözümü:

if ( this.getSupportFragmentManager().getBackStackEntryCount()>0 ) {
    var fgmt = this.getSupportFragmentManager().fragments[this.getSupportFragmentManager().getBackStackEntryCount()-1]
    if( fgmt is FgmtClassName ) {
        (fgmt as FgmtClassName).doSth()
    }
}

Basitleştirilmiş yol:

with ( this.getSupportFragmentManager() ) {
    if ( getBackStackEntryCount()>0 ) {
        var fgmt = fragments[getBackStackEntryCount()-1]
        if ( fgmt is FgmtClassName ) {
            (fgmt as FgmtClassName).doSth()
        }
    }
}

2

Bunu yapmanın kolay yolu:

Fragment fr=getSupportFragmentManager().findFragmentById(R.id.fragment_container);
String fragmentName = fr.getClass().getSimpleName();

1

Ana aktivitede, aktiviteye yeni bir fragman eklendiğinde onAttachFragment (Fragment fragment) yöntemi çağrılır. Bu yöntemde, geçerli parçanın örneğini alabilirsiniz. Ancak onAttachFragment yöntemi, bir parça backstack'ten çıkarıldığında, yani üst parçayı yığının üstüne almak için geri düğmesine basıldığında çağrılmaz. Hala bir parça aktivite içinde görünür hale geldiğinde ana faaliyet tetiklenen bir geri arama yöntemi arıyorum.


çok yakın! :-)
Blundell

Jetpack Navigasyon kütüphanesini kullanıyoruz
IgorGanapolsky

1

Kaydırılmış fragmanlarda, ViewPager sınıfını kullandığınızda mVeiwPager olduğunu varsayalım, geçerli fragman int numarasını almak için mViewPager.getCurrentItem () öğesini çağırabilirsiniz.

MainLayout.xml dosyasında

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context="unidesign.photo360.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="false"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:expanded="false">

        <android.support.v7.widget.Toolbar
            android:id="@+id/main_activity_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:title="@string/app_name">

        </android.support.v7.widget.Toolbar>

    </android.support.design.widget.AppBarLayout>


    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </android.support.v4.view.ViewPager>
    
</android.support.design.widget.CoordinatorLayout>

MainActivity.kt içinde

class MainActivity : AppCompatActivity() {
    
        lateinit var mViewPager: ViewPager
        lateinit var pageAdapter: PageAdapter
        
//      ...
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            
            pageAdapter = PageAdapter(supportFragmentManager)
            mViewPager = findViewById(R.id.view_pager)
//          ...
            }
            
        override fun onResume() {
          super.onResume()
          var currentFragment = pageAdapter.getItem(mViewPager.currentItem)
//         ...
          }


1

findFragmentByTagO kadar da uygun değil buldum . Eğer varsa String currentFragmentTagsizin içinde Activityveya ebeveyn Fragment, sen kaydetmek gerekir onSaveInstanceStateve bunu içine geri onCreate. Bunu bile, ne zaman Activityyeniden, onAttachFragmentdaha önce adı verilen edecektir onCreatesen kullanamaması için, currentFragmentTagiçinde onAttachFragment(örneğin. Dayalı bazı görünümlerini güncelleştirmekcurrentFragmentTag , çünkü henüz geri yüklenmemiş olabilir.

Aşağıdaki kodu kullanıyorum:

Fragment getCurrentFragment() {
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if(fragments.isEmpty()) {
        return null;
    }
    return fragments.get(fragments.size()-1);
}

Belge FragmentManagerdevlet olduğunu

Listedeki parçaların sırası, eklendiği veya eklendiği sıradır.

Geçerli parça türüne göre bir şeyler yapmanız gerektiğinde, getCurrentFragment() instance of MyFragmentyerine kullanın currentFragmentTag.equals("my_fragment_tag").

Not olduğu getCurrentFragment()içinde onAttachFragmenttakıldıktan almazsınız Fragment, ancak önceki ekli bir.


1

Bunu son zamanlarda yapmak zorunda kaldım ve buradaki cevapların hiçbiri bu senaryoya gerçekten uymadı.

Yalnızca bir parçanın görünür olacağından eminseniz (tam ekran), bu yüzden backstack'in üst kısmında ne olduğunu bulmak istersiniz. Örneğin, Kotliniçin Fragment:

import androidx.fragment.app.Fragment

fun Fragment.setVisibilityChangeListener(clazz: Class<out Fragment>, listener: (Boolean) -> Unit) {
    fragmentManager?.run {
        addOnBackStackChangedListener {
            val topFragmentTag = getBackStackEntryAt(backStackEntryCount - 1).name
            val topFragment = findFragmentByTag(topFragmentTag)
            listener(topFragment != null && topFragment::class.java == clazz)
        }
    }
}

Ve şöyle kullanın:

class MyFragment: Fragment {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        setVisibilityChangeListener(this::class.java) { visible -> 
            // Do stuff
        }
    }
}

1

Sizi geçerli parça kaynak kodunun kaynak koduna yönlendirecek bir URL ile logcat'te de kolayca yapabilirsiniz. İlk olarak, ana bilgisayar etkinliğine bir OnBackStackChangedListener eklemeniz gerekir -

activity.getChildFragmentManager().addOnBackStackChangedListener(backStackListener);

Ve OnBackStackChangedListener uygulaması -

    public FragmentManager.OnBackStackChangedListener backStackListener = () -> {

    String simpleName = "";
    String stackName = getStackTopName().trim();

    if (Validator.isValid(stackName) && stackName.length() > 0) {

      simpleName = stackName.substring(Objects.requireNonNull(stackName).lastIndexOf('.') + 1).trim();

      List<Fragment >
       fragmentList = getChildFragmentManager().getFragments();
      Fragment myCurrentFragment;

      for (int i = 0; i < fragmentList.size(); i++) {
       myCurrentFragment= fragmentList.get(i);
       if (myCurrentFragment.getClass().getSimpleName().equals(simpleName)) {
        //Now you get the current displaying fragment assigned in myCurrentFragment.
        break;
       }
       myFragment = null;
      }
     }


     //The code below is for the source code redirectable logcat which would be optional for you.
     StackTraceElement stackTraceElement = new StackTraceElement(simpleName, "", simpleName + ".java", 50);
     String fileName = stackTraceElement.getFileName();
     if (fileName == null) fileName = "";
     final String info = "Current Fragment is:" + "(" + fileName + ":" +
     stackTraceElement.getLineNumber() + ")";
     Log.d("now", info + "\n\n");
    };

Ve getStackTopName () yöntemi -

public String getStackTopName() {
    FragmentManager.BackStackEntry backEntry = null;
    FragmentManager fragmentManager = getChildFragmentManager();
    if (fragmentManager != null) {
        if (getChildFragmentManager().getBackStackEntryCount() > 0)
            backEntry = getChildFragmentManager().getBackStackEntryAt(
                    getChildFragmentManager().getBackStackEntryCount() - 1
            );
    }
    return backEntry != null ? backEntry.getName() : null;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.