Jak uzyskać aktualnie wyświetlany fragment?


444

Gram z fragmentami w Androidzie.

Wiem, że mogę zmienić fragment, używając następującego kodu:

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

Moje pytanie brzmi: w pliku Java, jak mogę uzyskać aktualnie wyświetlaną instancję Fragment?



Odpowiedzi:


453

Po dodaniu fragmentu do transakcji należy użyć znacznika.

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

... a później, jeśli chcesz sprawdzić, czy fragment jest widoczny:

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

Zobacz także http://developer.android.com/reference/android/app/Fragment.html


74
Ok, ale potrzebuję sposobu, aby natychmiast uzyskać aktualnie wyświetlaną instancję Fragmentu, nie sprawdzać iteracyjnie wszystkich fragmentów, a następnie zdecydować, który fragment jest teraz wyświetlany na ekranie. Myślę, że twoja odpowiedź wymaga mojego kodu, aby iteracyjnie sprawdzić każdy z moich fragmentów i znaleźć ten widoczny ...
Leem.fin

33
Tak, ale jednocześnie może być widoczny więcej niż jeden fragment. Nie ma więc nic takiego jak „jedyny aktywny fragment” ....
ramdroid

6
Ok, nawet wyświetlono kilka fragmentów, wciąż potrzebuję sposobu, aby je zdobyć ... i sposobu, który jest lepszy niż iteracyjne sprawdzenie każdego z moich fragmentów. Jestem troska o „je” metoda jak getDisplayedFragment (), ale nie wiem, czy istnieje taka metoda w Androidzie
Leem.fin

2
Nie wiem, dlaczego jest to dla ciebie problem ... Zazwyczaj masz tylko kilka fragmentów w działaniu i sprawdzenie, czy są widoczne, nie powinno być problemem.
ramdroid

12
Dlaczego wszyscy popierają tę odpowiedź? Jasne, to niezły fragment kodu, ale nie odpowiada na pytanie, aby uzyskać konkretny fragment po tagu. ALE Asker chce aktualnie wyświetlanego fragmentu, co oznacza, że ​​nie wie, który fragment jest wyświetlany. Tak, może istnieć wiele fragmentów, ale po przeczytaniu pytania w interfejsie użytkownika wyświetla się tylko 1 fragment ... Przepraszam, że muszę głosować, ponieważ nie odpowiada on na kontekst pytania.
angryITguy

410

Wiem, że to stary post, ale wcześniej miałem z tym problem. Znaleziono rozwiązanie, które miało to zrobić w onBackStackChanged()funkcji odsłuchu

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

    }

To działało dla mnie, ponieważ nie chciałem powtarzać każdego fragmentu, który muszę znaleźć, który jest widoczny. Mam nadzieję, że pomoże to również komuś innemu.


13
Dokładnie to, czego szukałem podczas pracy z funkcją onBackPressed () po obróceniu ekranu za pomocą szuflady nawigacji. Dziękujemy za przyjście i podzielenie się tym.
ShortFuse

1
Czy findFragmentById nie wykonuje iteracji przez wszystkie fragmenty wewnętrznie? :)
Andrew Senner

46
w przypadku .getFragmentManagerraportów typu niezgodnego, tak jak w moim przypadku, dzieje się tak, ponieważ korzystałem z android.support.app.v4.Fragment, w którym to przypadku właściwą metodą jestgetSupportFragmentManager
Răzvan Barbu

3
lub możesz użyć findFragmentByTag()zamiast findFragmentById, jeśli podałeś tag do fragmentowania podczas dodawania go dofragmentManager.beginTransaction() .add(containerID, frag, fragmentTag) .addToBackStack(fragmentTag) .commit();
DeltaCap019

@AndrewSenner, ma na myśli, że nie chciał tego robić wprost :)
Farid

161

Oto moje rozwiązanie, które uważam za przydatne w scenariuszach z niskim fragmentem

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
fragmentmoże mieć wartość null w niektórych scenariuszach, na przykład podczas otwierania tylnego stosu. Więc lepiej użyj if (fragment != null && fragment.isVisible()).
cprcrack

8
metoda niekompletna, ponieważ jest możliwe, że nie widać tylko jednego fragmentu
wypisz

Jeśli żaden fragment nie jest widoczny, fragmentManager.getFragments () zwróci NULL, co spowoduje, że NPE powie „Próba wywołania metody interfejsu java.util.Iterator java.util.List.iterator ()” w odniesieniu do obiektu NULL ”. Dlatego pętla for powinna być otoczona prostym sprawdzeniem: if (fragmenty! = Null)
Pranav Mahajan

Co jeśli więcej niż jeden fragment jest widoczny?
Shivaraj Patil

5
Technicznie należy to oznaczyć jako odpowiedź na podstawie pytania. Pytający chce aktualnie wyświetlanego fragmentu, nie wiedząc, który to fragment. Inne odpowiedzi wciąż zdobywają fragmenty według tagu
złyITguy

76

Za każdym razem, gdy pokazujesz fragment, musisz umieścić go w plecaku:

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

A kiedy potrzebujesz uzyskać aktualny fragment, możesz użyć tej metody:

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

4
Jestem całkiem pewien, że ta technika nie zadziała w przypadku fragmentów używanych z ViewPager, ponieważ nie są one dodawane przez znacznik. Po prostu to tam rzucam.
loeschg

3
Wydaje się, że działa to tylko wtedy, gdy zadzwonisz addToBackStack(tag), ale co zrobić, jeśli nie chcesz dodać fragmentu do tylnego stosu?
cprcrack

1
Działa to tylko wtedy, gdy twój tag jest taki sam jak nazwa stosu tylnego, co wydaje się niezwykłe.

Co się stanie, jeśli dodasz 5 fragmentów w tej samej transakcji?
Kevin Lam

Być może miło jest powiedzieć, że jeśli wywołasz addToBackStack (null) dla jakiegoś Fragmentu, w którym nie potrzebujesz nazwy, metoda getName () może zwrócić null i otrzymasz NPE. @ dpk, docu mówi: Uzyskaj nazwę, która została dostarczona do FragmentTransaction.addToBackStack (String) podczas tworzenia tego wpisu. Dodaj także zerowe sprawdzenie, czy EntryCount ma wartość 0, i próbujesz otrzymać najwyższy wpis.
JacksOnF1re

23

To, czego używam do znalezienia bieżącego fragmentu wyświetlania, znajduje się poniżej kodu. To jest proste i do tej pory działa dla mnie. Działa w aktywności, która zawiera fragmenty

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

3
Powinieneś sprawdzić, aby upewnić się, że liczba> 0, aby get (count-1) nie generował wyjątku IndexOutofBoundsException
kehers

@tainy to nie da fragmentu, który został zastąpiony, ale nie został dodany do backstacka. Prawda? Jeśli tak, to czy mogę to uzyskać za pomocą argumentu tag?
cafebabe1991

Wywołanie getFragments nie da ci fragmentów w kolejności, w jakiej zostały dodane po wywołaniu popBackStack (null, FragmentManager.POP_BACK_STACK_INCLUSIVE) na nim i dodania kolejnych fragmentów.
LEHO

jeśli aktywność ma więcej niż jeden Fragment widoczny, Twoja droga jest zła. Na przykład: ViewPager z fragmentami. jak wiadomo getBackStackEntryCount () zwraca numer Transakcji, a nie liczbę fragmentów
HungNM2

Powinieneś sprawdzić fragManager.getFragments().size()zamiast, getBackStackEntryCount()ponieważ niekoniecznie są one równe (w moim przypadku). W przeciwnym razie możesz dostać awarię z IndexOutOfBoundsException
RustamG

19

Sposób Kotlina;

val currentFragment = supportFragmentManager.fragments.last()

Działa tylko z API 26 i
nowszymi

1
@ibit, co masz na myśli mówiąc, że działa tylko na API 26 i nowszych wersjach? Próbowałem na emulatorze API 19 działającym dobrze.
HendraWD,

@HendraWD masz rację! Miałem na myśli funkcję w ramach frameworka getFragments(), którą jest API 26 i nowsze.
ibit

2
dbać. Jeśli wcześniej nie masz stosu fragmentów, może to spowodować pusty wyjątek!
Jetwiz,

To nie działa? java.lang.ClassCastException: androidx.navigation.fragment.NavHostFragment nie mogą być oddane do Fragment
coolcool1994

13

Reaktywne sposób:

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

7
jak to jest reaktywne? Używasz obserwowalnego, ale wyemituje się tylko raz
Tim

6
I to tylko przesada. Prosty ulepszony forloop zrobiłby to samo, może nawet szybciej.
Peterstev Uremgba

używanie reaktywnego strumienia do samego streamu API nie jest tak inteligentne, w rzeczywistości, jak powiedzieli, że to przesada, użyj Steam Java API, jeśli chcesz traktować listę jako strumień i zastosować interfejs API
AndroidLover

13

Moja metoda oparta jest na try / catch:

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

Ale może być lepszy sposób ...


1
Moje pytanie brzmi: jak uzyskać aktualnie wyświetlany fragment, co oznacza, że ​​może być wiele fragmentów, chcę tylko uzyskać instancję aktualnie wyświetlanego fragmentu, dlaczego warto używać (MyFragment)? Mam na myśli, że może to być dowolny fragment Fragmentu na ekranie ... i chcę, aby ten był aktualnie wyświetlany.
Leem.fin

MY_TAG_FRAGMENT jest znacznikiem fragmentu, który utworzyłem przed użyciem zastępowania, takiego jak: fragmentTransaction.replace (R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT);
Thordax,

Jeśli mam wiele fragmentów, czy mogę użyć jednego znacznika dla wszystkich fragmentów podczas wywołania .replace (...)?
Leem.fin

Tak, nie ma problemu, użyj tego kodu: fragmentTransaction.replace (R.id.FL_MyFragment, MyFragment, MY_TAG_FRAGMENT); i może pójść dobrze.
Thordax,

1
Cóż, naprawdę nie rozumiem, o co mi chodzi, to znaczy, że potrzebuję sposobu, aby natychmiast uzyskać aktualnie wyświetlaną instancję Fragmentu, nie iteracyjnie sprawdzać wszystkie fragmenty, a następnie zdecydować, który fragment jest teraz wyświetlany na ekranie.
Leem.fin

11

Cóż, to pytanie zyskało wiele poglądów i uwagi, ale wciąż nie zawierało najłatwiejszego rozwiązania z mojej strony - użycia getFragments ().

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

1
Niestety, nie zawsze jest to prawdą, getSupportFragmentManager().getFragments() daje ci listę, ale może zawierać wartości zerowe, jeśli najnowszy fragment został właśnie wyskakujący z backstacka. Eq: Jeśli sprawdzisz swoją drogę wewnątrz onBackStackChanged()metody i wywołasz popBackStack()gdzieś, to mCurrentFragmentbędzie null.
Stumi,

@Stumi Dzięki za tę informację. Tak, brzmi jak jeden z wielu dziwnych problemów cyklu życia w Androidzie.
Nativ

9

Możesz zapytać, który fragment jest załadowany do ramki treści Działania, i pobrać klasę fragmentu lub fragment „prostej nazwy” (jako ciąg).

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

Stosowanie:

Log.d(TAG, getCurrentFragment());

Wyjścia:

D/MainActivity: FragOne

8

Jest trochę późno, ale dla każdego, kto jest zainteresowany: jeśli znasz indeks żądanego fragmentu w FragmentManager, po prostu uzyskaj odwołanie do niego i sprawdź, czy jest funkcja isMenuVisible ()! tutaj:

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

Jeśli jest truewidoczny dla użytkownika i tak dalej!


1
O dziwo, było to jedyne wymienione tutaj rozwiązanie, które działało dla mnie. Jednocześnie, wiele fragmentów może mieć isVisible() == true, getView() != null. Dodatkowo w moim kodzie getBackStackEntryCountjest zawsze zero. Mimo że nie korzystam z menu, isMenuVisible()to jak dotąd jedyna dyskryminacja, która wydaje się niezawodnie wskazywać na aktualnie „aktywny” fragment. 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

Jeśli się tu dostaniesz i korzystasz z Kotlin:

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

R.id.fragment_containerto miejsce, w idktórym fragmentprezentuje się na nichactivity

Lub jeśli chcesz ładniejszego rozwiązania:

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

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

5

Zainspirowany odpowiedzią Tainy , oto moje dwa centy. Trochę zmodyfikowany w stosunku do większości innych implementacji.

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

Zamień na "myActivity"„to”, jeśli jest to Twoja bieżąca aktywność, lub użyj odniesienia do swojej aktywności.


5

Jest to metoda nazywa findFragmentById()się SupportFragmentManager. Używam go w kontenerze aktywności, takim jak:

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

Tak zdobędziesz swój prąd Fragment. Jeśli masz niestandardowy Fragmenti chcesz sprawdzić, co Fragmentto jest, zwykle używam instanceof:

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


4

Jest to prosty sposób na uzyskanie bieżącego fragmentu.

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

Odpowiedź Seva działa, gdy naciśniesz przycisk Wstecz lub w inny sposób zmienisz plecak.

Zrobiłem jednak coś nieco innego. Mam konfigurację detektora zmian cofnięcia na podstawowym fragmencie i jego pochodnych fragmentach, a ten kod znajduje się w detektorze:

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

To dla mnie praca. Mam nadzieję, że to komuś pomoże.

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

3

Jeśli pobierasz bieżącą instancję Fragmentu z działania nadrzędnego, możesz to zrobić

findFragmentByID(R.id.container);

To faktycznie jest bieżącą instancją fragmentu, który jest zapełniany w widoku. Miałem ten sam problem. Musiałem załadować ten sam fragment dwa razy, trzymając jeden z powrotem na stos.

Następująca metoda nie działa. Po prostu dostaje fragment, który ma tag. Nie trać czasu na tę metodę. Jestem pewien, że ma on swoje zastosowania, ale uzyskanie najnowszej wersji tego samego fragmentu nie jest jednym z nich.

findFragmentByTag()

3

Sprawdź to rozwiązanie. Udało mi się zdobyć obecny Fragment.

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

To działa z Jetpack?
IgorGanapolsky

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

Sądzę, że jest to najprostsza odpowiedź na to pytanie. Mam nadzieję, że to pomoże.


2

Oto rozwiązanie Kotlin:

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

Uproszczony sposób:

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

2

Łatwy sposób to zrobić:

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

1

W głównym działaniu metoda onAttachFragment (fragment fragmentu) jest wywoływana, gdy do działania dołączany jest nowy fragment. W tej metodzie można uzyskać instancję bieżącego fragmentu. Jednak metoda onAttachFragment nie jest wywoływana, gdy fragment jest usuwany ze stosu, tj. Gdy naciśnięty jest przycisk Wstecz, aby uzyskać górny fragment na szczycie stosu. Nadal szukam metody wywołania zwrotnego, która jest uruchamiana w głównej aktywności, gdy fragment staje się widoczny w tej aktywności.


tak blisko! :-)
Blundell

Używamy biblioteki nawigacji Jetpack
IgorGanapolsky

1

W przypadku przewijanych fragmentów, gdy używasz instancji klasy ViewPager, załóżmy, że mVeiwPager, możesz wywołać mViewPager.getCurrentItem () w celu uzyskania bieżącego numeru int.

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

w 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

Odkryłem, że findFragmentByTagto nie jest wygodne. Jeśli masz String currentFragmentTagu swojego Activitylub rodzica Fragment, musisz go zapisać onSaveInstanceStatei przywrócić onCreate. Nawet jeśli to zrobisz, po Activityodtworzeniu onAttachFragmentzostanie wywołany wcześniej onCreate, więc nie możesz użyć currentFragmentTagw onAttachFragment(np. Zaktualizować niektórych widoków na podstawiecurrentFragmentTag ), ponieważ może nie zostać jeszcze przywrócone.

Używam następującego kodu:

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

Dokument FragmentManagerstwierdzający, że

Kolejność fragmentów na liście to kolejność, w której zostały dodane lub dołączone.

Jeśli musisz robić rzeczy na podstawie bieżącego typu fragmentu, po prostu użyj getCurrentFragment() instance of MyFragmentzamiast currentFragmentTag.equals("my_fragment_tag").

Zauważ, że getCurrentFragment()w onAttachFragmentnie otrzyma załączania Fragment, ale poprzedni załączony.


1

Musiałem to zrobić bardzo niedawno i żadna z odpowiedzi tutaj nie pasowała do tego scenariusza.

Jeśli masz pewność, że widoczny będzie tylko jeden fragment (pełny ekran), więc naprawdę chcesz znaleźć to, co znajduje się na górze plecaka. Na przykład, jak Kotlinna 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)
        }
    }
}

I używaj go w następujący sposób:

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

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

1

Możesz to zrobić bardzo łatwo również za pomocą adresu URL w logcat, który przekieruje cię do kodu źródłowego bieżącego kodu źródłowego fragmentu. Najpierw musisz dodać OnBackStackChangedListener do działania hosta, takiego jak -

activity.getChildFragmentManager().addOnBackStackChangedListener(backStackListener);

A implementacja OnBackStackChangedListener to -

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

A metoda getStackTopName () to -

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;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.