Як отримати фрагмент, що відображається в даний момент?


444

Я граю з фрагментами в Android.

Я знаю, що можу змінити фрагмент, використовуючи наступний код:

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();

Моє запитання полягає у тому, що у файлі Java, як я можу отримати екземпляр Fragment, що відображається в даний момент?



1
Можливий дублікат Get the current fragment object
Sruit A.Suk

Відповіді:


453

Додаючи фрагмент у транзакцію, ви повинні використовувати тег.

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

... і пізніше, якщо ви хочете перевірити, чи видно фрагмент:

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

Дивіться також http://developer.android.com/reference/android/app/Fragment.html


74
Гаразд, але мені потрібен спосіб негайно отримати наразі відображений екземпляр фрагмента, а не ітеративно перевіряти всі фрагменти, а потім вирішувати, який фрагмент тепер відображатиметься на екрані. Я думаю, що у вашій відповіді потрібен мій код, щоб ітеративно перевірити кожен з моїх фрагментів і виявити видимий ...
Leem.fin

33
Так, але одночасно може бути видно більше одного фрагмента. Тож немає нічого подібного до "єдиного активного фрагмента" ....
ramdroid

6
Гаразд, навіть там відображається кілька фрагментів, мені все одно потрібен спосіб їх отримання ... і спосіб, який краще, ніж ітеративно перевірити кожен мій фрагмент. Я стурбований тим, що "отримай їх" таким методом, як getDisplayedFragment (), але не впевнений, чи існує такий метод в Android
Leem.fin

2
Я не знаю, чому це для вас проблема ... У вас зазвичай є лише кілька фрагментів у діяльності, і перевірити їх, чи вони видимі чи ні, насправді не повинно бути проблемою.
ramdroid

12
Чому всі підтримують цю відповідь? Звичайно, це приємний шматочок коду, але не відповідає на питання, щоб отримати конкретний фрагмент за тегом. АЛЕ Анкер хоче, щоб фрагмент, що відображається в даний момент, відображався, а значить, він не знає, який фрагмент відображається. Так, може бути декілька фрагментів, але при читанні запитання випливає, що в інтерфейсі відображається лише 1 фрагмент .... Вибачте, довелося подати заявку, оскільки він не відповідає контексту питання.
сердитийТіг

410

Я знаю, що це стара публікація, але раніше з цим теж були проблеми. Знайшов рішення, яке повинно було зробити це у функції onBackStackChanged()прослуховування

  @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();

    }

Це спрацювало для мене, оскільки я не хотів повторювати кожен фрагмент, я повинен знайти той, який видно. Сподіваюсь, це допоможе і комусь іншому.


13
Саме те, що я шукав при роботі з OnBackPress () після обертання екрана за допомогою навігаційного ящика. Дякуємо, що повернулися, щоб поділитися цим.
ShortFuse

1
Не знайде іFragmentById ітерацію через усі фрагменти внутрішньо? :)
Ендрю Сеннер

46
у випадках, коли .getFragmentManagerзвіти несумісні типу, як це було у моєму випадку, це тому, що я використовував android.support.app.v4.Fragment, у такому випадку правильний метод використанняgetSupportFragmentManager
Răzvan Barbu,

3
або ви можете використовувати findFragmentByTag()замість findFragmentById, якщо ви додали тег до фрагменту, додаючи його вfragmentManager.beginTransaction() .add(containerID, frag, fragmentTag) .addToBackStack(fragmentTag) .commit();
DeltaCap019,

@AndrewSenner, він означає, що він не хотів це робити явно :)
Farid

161

Ось моє рішення, яке я знаходжу в нагоді для сценаріїв з невеликими фрагментами

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
fragmentможе бути недійсним у певних сценаріях, наприклад, коли ви вставляєте задній стек. Тож краще використовувати if (fragment != null && fragment.isVisible()).
cprcrack

8
метод неповний, тому що можливо, видно не один фрагмент
реєстр

Якщо фрагмент не видно, тоді fragmentManager.getFragments () поверне NULL, що призведе до NPE, кажучи "Спроба викликати метод інтерфейсу 'java.util.Iterator java.util.List.iterator ()' на посилання на об'єкт NULL". Тому цикл for повинен бути оточений простим перевіркою: якщо (фрагменти! = Null)
Пранів Махаджан

Що робити, якщо видно більше одного фрагмента?
Шиварадж Патіль

5
Технічно це має бути позначено як відповідь на основі запитання. Asker хоче, щоб даний фрагмент відображався, не знаючи, який це фрагмент. Інші відповіді продовжують отримувати фрагменти за тегом
сердитийTguy

76

Кожен раз, коли ви показуєте фрагмент, ви повинні помістити його в теку:

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

І тоді, коли вам потрібно отримати поточний фрагмент, ви можете скористатися цим методом:

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

4
Я впевнений, що ця методика не працюватиме для фрагментів, що використовуються у ViewPager, оскільки вони не додаються тегом. Просто кинувши це там.
loeschg

3
Це, здається, працює лише під час дзвінка addToBackStack(tag), але що робити, якщо ви не хочете додати фрагмент до заднього стека?
cprcrack

1
Це працює лише в тому випадку, якщо ваш тег збігається з назвою заднього стека, що здається незвичним.

Що станеться, якщо ви додали 5 фрагментів за одну транзакцію?
Кевін Лам

Можливо, приємно сказати, що якщо ви викликаєте addToBackStack (null) для якогось фрагмента, де вам не потрібно імені, метод getName () може повернути нуль і ви отримаєте NPE. @ dpk, docu каже: Під час створення цього запису отримайте ім’я, яке було надано FragmentTransaction.addToBackStack (String). Також додайте нульову перевірку, якщо EntryCount дорівнює 0, і ви намагаєтеся отримати верхній запис.
JacksOnF1re

23

Що я використовую для пошуку поточного фрагмента, що відображається, знаходиться в коді нижче. Це просто і це працює для мене на даний момент. Він працює в тій діяльності, яка містить фрагменти

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

3
Ви повинні перевірити, щоб перерахувати кількість> 0, щоб get (count-1) не кидав IndexOutofBoundsException
kehers

@tainy цей звичай не дасть фрагмент, який був замінений, але не доданий до рюкзака. Право? Якщо так, то чи можу я отримати це за допомогою аргументу тегу?
cafebabe1991

Виклик getFragments не надасть вам фрагментів того порядку, яким вони були додані після виклику popBackStack (null, FragmentManager.POP_BACK_STACK_INCLUSIVE) на ньому, та додасть більше фрагментів.
LEHO

якщо в діяльності видно більше одного фрагмента, ваш шлях неправильний. Наприклад: ViewPager з фрагментами. як мені відомо getBackStackEntryCount () номер повернення транзакції, а не кількість фрагмента
HungNM2

Ви повинні перевірити fragManager.getFragments().size()замість того getBackStackEntryCount(), що вони не обов'язково рівні (що є моїм випадком). В іншому випадку ви можете отримати збій з IndexOutOfBoundsException
RustamG

19

Шлях Котліна;

val currentFragment = supportFragmentManager.fragments.last()

Працює лише над API 26 і вище
ibit

1
@ibit, що ти маєш на увазі, коли працює лише на API 26 і вище? Я спробував на емуляторі API 19 працює добре.
HendraWD

@HendraWD ви праві! Я мав на увазі функцію у функції фреймворків getFragments(), яка є API 26 і вище.
ibit

2
піклуватися. Якщо раніше у вас немає фрагмента стека, це може спричинити порожнє виняток!
Jetwiz

Це не працює? java.lang.ClassCastException: androidx.navigation.fragment.NavHostFragment не може бути
передано

13

Реактивний спосіб:

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

7
як це реагує? Ви користуєтеся спостережуваним, але він випромінює лише один раз
Тим

6
І це просто надмірність. Простий розширений forloop зробив би так само, можливо, навіть швидше.
Петерстев Уремгба

використовувати реактивний потік для просто потоку api - це не так розумно, адже, як вони сказали, це надмірне використання парової Java8 api, якщо ви хочете розглянути список як потік і застосувати фільтр api
AndroidLover

13

Мій метод заснований на спробі / лові так:

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

Але може бути і кращий спосіб ...


1
Моє запитання - як отримати фрагмент, що відображається в даний момент, це означає, що може бути багато фрагментів, я хочу лише отримати екземпляр відображеного в даний час, навіщо використовувати (MyFragment) ?? Я маю на увазі, що це може бути будь-який фрагмент відображення на екрані ... і я хочу отримати відображений в даний час.
Leem.fin

MY_TAG_FRAGMENT - тег створеного мною фрагмента перед використанням заміни, наприклад: fragmentTransaction.replace (R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT);
Тордак

Якщо у мене є кілька фрагментів, чи можу я використовувати один тег для всіх фрагментів при виклику .replace (...)?
Leem.fin

Так, немає проблем, використовуйте цей код: fragmentTransaction.replace (R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT); і це може піти добре.
Тордак

1
Ну, я дійсно не розумію вашу думку, я маю на увазі, що мені потрібен спосіб негайно отримати екземпляр, що відображається в даний момент, фрагмент, а не ітеративно перевіряти всі фрагменти, а потім вирішувати, який фрагмент тепер відображатиметься на екрані.
Leem.fin

11

Ну, це запитання отримало багато поглядів та уваги, але все ж не містило найпростішого рішення з мого кінця - використовувати getFragments ().

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

1
На жаль, це не завжди відповідає дійсності, getSupportFragmentManager().getFragments() повертає вам список, але це може містити нульові значення, якщо останній фрагмент щойно вискакував із задніх верств. Eq: Якщо ви перевірите свій шлях всередині onBackStackChanged()методу і ви popBackStack()десь зателефонуєте , тоді mCurrentFragmentбуде null.
Стумі

@Stumi Дякую за цю інформацію. Так, це схоже на одну з багатьох дивних проблем життєвого циклу в Android.
Nativ

9

Ви можете запитати, який фрагмент завантажено у ваш вміст кадрів "Діяльність", і отримати клас фрагмента або фрагмент "просте ім'я" (як рядок).

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

Використання:

Log.d(TAG, getCurrentFragment());

Виходи:

D/MainActivity: FragOne

8

Це трохи пізно, але для тих, хто цікавиться: Якщо ви знаєте індекс потрібного фрагмента у FragmentManager, просто отримайте посилання на нього і перевірте функцію isMenuVisible ()! тут:

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

Якщо trueйого видно користувачеві тощо!


1
Як не дивно, це єдине перелічене тут рішення, яке працювало на мене. У той же час, безліч фрагментів може бути isVisible() == true, getView() != null. Плюс у моєму коді getBackStackEntryCountзавжди дорівнює нулю. Хоча я не використовую меню, isMenuVisible()поки що єдиний дискримінант, який, здається, надійно вказує на "активний" фрагмент. 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

Якщо ви потрапили сюди, і ви використовуєте Kotlin:

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

R.id.fragment_containerце те, idде fragmentпредставлення на їхactivity

Або якщо ви хочете приємніше рішення:

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

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

5

Натхненний відповіддю Таїні , ось два мої центи. Трохи модифікований від більшості інших реалізацій.

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"на "це", якщо це ваша поточна діяльність або використовуйте посилання на свою діяльність.


5

Існує метод, викликаний findFragmentById()в SupportFragmentManager. Я використовую його в контейнері діяльності, наприклад:

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

Ось як отримати свій струм Fragment. Якщо у вас є звичай Fragmentі вам потрібно перевірити, що Fragmentце таке, я зазвичай використовую instanceof:

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

5

Якщо ви використовуєте AndroidX Navigation:

val currentFragment = findNavController(R.id.your_navhost).?currentDestination

Для отримання додаткової інформації про цей компонент навігації: https://developer.android.com/guide/navigation/navigation-getting-started


Це не компілюється
ІгорГанапольський

1
Він складатиметься лише в тому випадку, якщо ви правильно налаштували навігацію AndroidX і якось називали ваш navHost your_navhost.
Кори Рой

4

Це простий спосіб отримати поточний фрагмент ..

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 працює, коли ви натискаєте кнопку "назад" або іншим чином змінюєте ранець.

Хоча я щось дещо інакше зробив. У мене на базовому фрагменті та його похідних фрагментах встановлена ​​програма прослуховування змін у задніх куточках, і цей код знаходиться у слухачі:

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

Це робота для мене. Я сподіваюся, що це когось підкаже.

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

3

Якщо ви отримуєте поточний екземпляр Fragment від батьківської діяльності, ви можете просто

findFragmentByID(R.id.container);

Це фактично отриманий поточний екземпляр фрагмента, заповненого на подання. У мене було те саме питання. Мені довелося завантажувати один і той же фрагмент двічі, зберігаючи один на ранці.

Наступний метод не працює. Він просто отримує фрагмент, який має тег. Не витрачайте час на цей метод. Я впевнений, що це має його використання, але отримати найновішу версію того ж Фрагменту - це не одна з них.

findFragmentByTag()

3

Оформити замовлення. Мені працювало, щоб отримати поточний Фрагмент.

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");
}

Це працює з Jetpack?
ІгорГанапольський

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

Ну, мабуть, це найпростіша відповідь на це питання. Я сподіваюся, що це допомагає.


2

Ось рішення Котліна:

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

Спрощений спосіб:

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

2

Простий спосіб зробити це:

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

1

У основній діяльності метод onAttachFragment (Fragment fragment) викликається, коли до активності додається новий фрагмент. У цьому методі ви можете отримати екземпляр поточного фрагмента. Однак метод onAttachFragment не викликається, коли фрагмент вискакує з backstack, тобто коли натискається кнопка "назад", щоб отримати верхній фрагмент на вершині стека. Я все ще шукаю метод зворотного виклику, який запускається в основній діяльності, коли фрагмент стає видимим усередині діяльності.


так так близько! :-)
Блонделл

Ми використовуємо бібліотеку навігації Jetpack
ІгорГанапольський

1

У разі прокручування фрагментів, коли ваш екземпляр класу ViewPager, припустимо, mVeiwPager, ви можете зателефонувати mViewPager.getCurrentItem (), щоб отримати поточний номер фрагмента int.

в MainLayout.xml

<?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

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

Я знайшов findFragmentByTagце не так зручно. Якщо у вас є String currentFragmentTagу вашому Activityабо батько Fragment, ви повинні зберегти його в onSaveInstanceStateі відновити його в onCreate. Навіть якщо ви зробите це, коли Activityвідтворена, onAttachFragmentбуде викликатися до onCreate, так що ви не можете використовувати currentFragmentTagв onAttachFragment(наприклад, оновити деякі уявлення , засновані наcurrentFragmentTag ), тому що це , можливо , ще не відновлена.

Я використовую такий код:

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

У документі FragmentManagerзазначено, що

Порядок фрагментів у списку - це порядок їх додавання чи додавання.

Коли вам потрібно робити матеріали на основі поточного типу фрагменту, просто використовуйте getCurrentFragment() instance of MyFragmentзамість цьогоcurrentFragmentTag.equals("my_fragment_tag") .

Зверніть увагу, що getCurrentFragment()в onAttachFragmentне вийде вкладення Fragment, а попереднє додане.


1

Мені довелося це зробити зовсім недавно, і жодна з відповідей тут справді не підходила до цього сценарію.

Якщо ви впевнені, що лише один фрагмент буде видно (на весь екран), то дуже хочеться знайти те, що знаходиться у верхній частині рюкзака. Наприклад, як Kotlinдля 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)
        }
    }
}

І використовувати його так:

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

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

1

Ви можете зробити це дуже легко також за допомогою URL-адреси в logcat, яка перенаправить вас на вихідний код поточного вихідного коду фрагмента. По-перше, вам потрібно додати OnBackStackChangedListener у активності хоста, наприклад -

activity.getChildFragmentManager().addOnBackStackChangedListener(backStackListener);

А реалізація OnBackStackChangedListener -

    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");
    };

А метод getStackTopName () -

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.