Как получить отображаемый фрагмент?

448

Я играю с фрагментами в 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, как я могу получить отображаемый в данный момент экземпляр фрагмента?

Leem.fin
источник
Связанные - stackoverflow.com/a/21104084/80428
Джей Уик,
1
Возможный дубликат Получить текущий фрагмент объекта
Sruit A.Suk

Ответы:

454

Когда вы добавляете фрагмент в вашу транзакцию, вы должны использовать тег.

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

ramdroid
источник
74
Хорошо, но мне нужен способ немедленно получить текущий отображаемый экземпляр фрагмента, а не итеративно проверять все фрагменты, а затем решать, какой фрагмент теперь отображается на экране. Я думаю, что ваш ответ нуждается в моем коде для итеративной проверки каждого из моих фрагментов и обнаружения видимого ...
Leem.fin
33
Да, но одновременно может быть видно более одного фрагмента. Так что нет ничего похожего на «единственный активный фрагмент» ....
ramdroid
6
Хорошо, даже если отображается несколько фрагментов, мне все еще нужен способ их получить ... и способ, который лучше, чем итеративная проверка каждого из моих фрагментов. Я обеспокоен "получить их" методом, подобным getDisplayedFragment (), но не уверен, есть ли такой метод в Android
Leem.fin
2
Я не знаю, почему это проблема для вас ... У вас обычно есть только несколько фрагментов в упражнении, и это не должно быть проблемой, чтобы проверить их, если они видны или нет.
ramdroid
13
Почему все голосуют против этого ответа? Конечно, это хороший кусок кода, но он не отвечает на вопрос, чтобы получить определенный фрагмент по тегу. НО Аскер хочет отображаемый в данный момент фрагмент, а это значит, что он не знает, какой фрагмент отображается. Да, может быть несколько фрагментов, но при чтении вопроса в интерфейсе отображается только 1 фрагмент .... Извините, пришлось понизить голос, потому что он не отвечает контексту вопроса.
angryITguy
411

Я знаю, что это старый пост, но раньше у него тоже были проблемы. Нашел решение, которое должно было сделать это в 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();

    }

Это сработало для меня, так как я не хотел перебирать каждый фрагмент, чтобы найти видимый. Надеюсь, это поможет кому-то еще.

Sev
источник
13
Именно то, что я искал, когда имел дело с onBackPressed () после поворота экрана с помощью окна навигации. Спасибо, что вернулись, чтобы поделиться этим.
ShortFuse
1
Разве findFragmentById не выполняет внутреннюю перебор всех фрагментов? :)
Эндрю Сеннер
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, он имеет в виду, что он не хотел делать это явно :)
Фарид
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
метод неполный, поскольку возможно, что виден не только один фрагмент
letroll
Если фрагмент не виден, то fragManager.getFragments () вернет NULL, что приведет к тому, что NPE скажет «Попытка вызвать метод интерфейса« java.util.Iterator java.util.List.iterator () »для ссылки на объект NULL». Поэтому цикл for должен быть окружен простой проверкой: if (фрагменты! =
Ноль
Что делать, если видно более одного фрагмента?
Шиварадж Патил
5
Технически это должно быть помечено как ответ, основанный на вопросе. Аскер хочет видеть отображаемый фрагмент, не зная, какой это фрагмент. Другие ответы продолжают получать фрагменты по тегу
angryITguy
76

Каждый раз, когда вы показываете фрагмент, вы должны поместить его в backstack:

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);
}
Dmitry_L
источник
4
Я вполне уверен, что этот метод не будет работать для фрагментов, используемых с ViewPager, так как они не добавляются тегами. Просто бросаю это там.
loeschg
3
Кажется, это работает только при вызове addToBackStack(tag), но что, если вы не хотите добавлять фрагмент в задний стек?
cprcrack
1
Это работает, только если ваш тэг совпадает с именем заднего стека, что кажется необычным.
Что произойдет, если вы добавили 5 фрагментов в одной транзакции?
Кевин Лам
Может быть, приятно сказать, что если вы вызываете addToBackStack (null) для некоторого фрагмента, для которого вам не нужно имя, метод getName () может вернуть значение null, и вы получите NPE. @ dpk, в документе сказано: Получите имя, которое было предоставлено 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
Вы должны убедиться, что count> 0, чтобы get (count-1) не генерировал
исключение
@tainy это не даст фрагмент, который был заменен, но не добавлен в backstack. Верно? Если да, то могу ли я получить его, используя аргумент тега?
cafebabe1991
Вызов getFragments не даст вам фрагменты в порядке их добавления после вызова для него popBackStack (null, FragmentManager.POP_BACK_STACK_INCLUSIVE) и добавления дополнительных фрагментов.
ЛЕХО
если в активности виден более одного фрагмента, ваш путь неверен. Например: ViewPager с фрагментами. как я знаю getBackStackEntryCount () возвращает номер транзакции, а не номер фрагмента
HungNM2
Вы должны проверить, fragManager.getFragments().size()а не getBackStackEntryCount()как они не обязательно равны (что мой случай). В противном случае вы можете получить сбой с помощью IndexOutOfBoundsException
RustamG
20

Котлин путь;

val currentFragment = supportFragmentManager.fragments.last()
Cafer Mert Ceyhan
источник
Работы по API 26 и выше только
ibit
1
@ibit Что ты имеешь в виду под работами над API 26 и выше? Я попробовал на API эмулятора 19 работает нормально.
HendraWD
@ HendraWD ты прав! Я имел в виду функцию в функции frameworks getFragments(), которая является API 26 и выше.
ibit
2
Береги себя. Если до того, как у вас не останется ни одного фрагмента стека, это может вызвать пустое исключение!
Jetwiz
Это не работает? java.lang.ClassCastException: androidx.navigation.fragment.NavHostFragment не может быть приведен к фрагменту
coolcool1994
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

Мой метод основан на try / catch:

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

Но может быть лучше ...

Thordax
источник
1
У меня вопрос, как получить отображаемый в данный момент фрагмент, а это значит, что фрагментов может быть много, я хочу получить только экземпляр отображаемого в данный момент фрагмента, зачем использовать (MyFragment) ?? Я имею в виду, что это может быть любой фрагмент фрагмента на экране ... и я хочу получить отображаемый в данный момент.
Leem.fin
MY_TAG_FRAGMENT - это тег фрагмента, который я создал перед использованием замены, например: fragTransaction.replace (R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT);
Thordax
Если у меня есть несколько фрагментов, могу ли я использовать один тег для всех фрагментов при вызове .replace (...)?
Leem.fin
Да, нет проблем, используйте этот код: fragTransaction.replace (R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT); и это может пойти хорошо.
Thordax
1
Ну, я действительно не понимаю вашу точку зрения, я имею в виду, что мне нужен способ немедленно получить текущий отображаемый экземпляр Fragment, а не итеративно проверять все фрагменты и затем решать, какой фрагмент теперь отображается на экране.
Leem.fin
11

Ну, этот вопрос получил много взглядов и внимания, но все еще не содержал самого простого решения с моей стороны - использовать getFragments ().

            List fragments = getSupportFragmentManager().getFragments();
            mCurrentFragment = fragments.get(fragments.size() - 1);
Натив
источник
1
К сожалению, это не всегда верно, getSupportFragmentManager().getFragments() возвращает список, но он может содержать нулевые значения, если последний фрагмент только что извлечен из backstack. Eq: Если вы проверите свой путь внутри onBackStackChanged()метода и вызовете popBackStack()куда-то, то mCurrentFragmentбудет null.
Стуми
@Stumi Спасибо за эту информацию. Да, звучит как одна из многих странных проблем жизненного цикла в Android.
Натив
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()это пока единственный дискриминант, который, кажется, надежно указывает на текущий «активный» фрагмент. ты
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
    }
}
pableiros
источник
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"на «this», если это ваша текущая деятельность, или используйте ссылку на вашу деятельность.

Нашего
источник
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

Ответ Сев работает, когда вы нажимаете кнопку «Назад» или иным образом меняете бэкстек.

Я сделал что-то немного другое, хотя. У меня есть настройка прослушивателя изменений обратного стека на базовом фрагменте и его производных фрагментах, и этот код находится в прослушивателе:

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
}
MCLLC
источник
3

Это работа для меня. Я надеюсь, что это кого-то поможет.

FragmentManager fragmentManager = this.getSupportFragmentManager();  
        String tag = fragmentManager
                    .getBackStackEntryAt(
                    fragmentManager
                    .getBackStackEntryCount() - 1)
                    .getName();
              Log.d("This is your Top Fragment name: ", ""+tag);
Cüneyt
источник
3

Если вы получаете текущий экземпляр Fragment от родительского действия, вы можете просто

findFragmentByID(R.id.container);

Это на самом деле получить текущий экземпляр фрагмента, который заполняется в представлении. Я была такая же проблема. Я должен был загрузить один и тот же фрагмент дважды, оставив один на backstack.

Следующий метод не работает. Он просто получает фрагмент с тегом. Не тратьте свое время на этот метод. Я уверен, что он использует его, но получить самую последнюю версию того же фрагмента не является одним из них.

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");
}
kmarin
источник
Это работает с Jetpack?
Игорь Ганапольский
2
getSupportFragmentManager().findFragmentById(R.id.content_frame).getClass().getSimpleName();

Ну, я думаю, это самый прямой ответ на этот вопрос. Надеюсь, это поможет.

Абхишек
источник
2

Вот решение Kotlin:

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()
        }
    }
}
anamkin
источник
2

Простой способ сделать это:

Fragment fr=getSupportFragmentManager().findFragmentById(R.id.fragment_container);
String fragmentName = fr.getClass().getSimpleName();
Биплоб Дас
источник
1

В основном упражнении метод onAttachFragment (фрагмент фрагмента) вызывается, когда к действию присоединяется новый фрагмент. В этом методе вы можете получить экземпляр текущего фрагмента. Однако метод onAttachFragment не вызывается, когда фрагмент извлекается из стека назад, т. Е. Когда нажимается кнопка «Назад», чтобы получить верхний фрагмент поверх стека. Я все еще ищу метод обратного вызова, который запускается в основном действии, когда фрагмент становится видимым внутри действия.

ufdeveloper
источник
так близко! :-)
Бланделл
Используем навигационную библиотеку 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()in onAttachFragmentне получит присоединение Fragment, но предыдущее прикрепленное.

Джеффри Чен
источник
1

Я должен был сделать это совсем недавно, и ни один из ответов здесь действительно не подходил для этого сценария.

Если вы уверены, что будет виден только один фрагмент (в полноэкранном режиме), так что действительно хотите найти то, что находится на вершине backstack. Например, 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;
}
Гх Мохаммед Эмон
источник