Ruft das aktuelle Fragmentobjekt ab

175

In meinem main.xmlhabe ich

  <FrameLayout
        android:id="@+id/frameTitle"
        android:padding="5dp"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:background="@drawable/title_bg">
            <fragment
              android:name="com.fragment.TitleFragment"
              android:id="@+id/fragmentTag"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" />

  </FrameLayout>

Und ich setze ein Fragmentobjekt wie dieses

FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment newFragment = new FragmentType1();
fragmentTransaction.replace(R.id.frameTitle, casinodetailFragment, "fragmentTag");

// fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

Es werden verschiedene Arten von Fragmentobjekten ( FragmentType2,FragmentType3,...) zu unterschiedlichen Zeiten festgelegt. Jetzt muss ich irgendwann herausfinden, welches Objekt gerade dort ist.

In kurzen brauche ich so etwas wie dies zu tun:

Fragment currentFragment = //what is the way to get current fragment object in FrameLayout R.id.frameTitle

Ich habe folgendes versucht

TitleFragment titleFragmentById = (TitleFragment) fragmentManager.findFragmentById(R.id.frameTitle);

und

    TitleFragment titleFragmentByTag = (TitleFragment) fragmentManager.findFragmentByTag("fragmentTag");

Aber beide Objekte (titleFragmentById und titleFragmentByTag) sindnull
Haben ich etwas verpasst?
Ich benutze Compatibility Package, r3und entwickle für API level 7.

findFragmentById()und findFragmentByTag()wird funktionieren, wenn wir Fragment mit fragmentTransaction.replaceoder gesetzt haben fragmentTransaction.add, aber return nullwenn wir das Objekt auf xml gesetzt haben (wie das, was ich in meinem getan habe main.xml). Ich glaube, ich vermisse etwas in meinen XML-Dateien.

Labeeb Panampullan
quelle
Verwandte - stackoverflow.com/a/21104084/80428
Jay Wick
Hilft Ihnen die Antwort von @CommonsWare, weil ich immer noch null bekomme?
IntoTheDeep

Antworten:

253

Jetzt muss ich irgendwann herausfinden, welches Objekt sich gerade dort befindet

Rufen Sie findFragmentById()an FragmentManagerund bestimmen Sie, welches Fragment sich in Ihrem R.id.frameTitleContainer befindet.

CommonsWare
quelle
1
Vielen Dank für Ihre Antwort. Es wird funktionieren, wenn wir Fragment mit fragmentTransaction.replace gesetzt haben oder fragmentTransaction.addaber nicht bekommen, wenn wir es auf xml gesetzt haben. Siehe meine Bearbeitung 2
Labeeb Panampullan
9
@ Labeeb P: Sie können keine in den Layoutressourcen deklarierten Fragmente ändern.
CommonsWare
Das Erstellen einer Klasse für die aktuell sichtbare Registerkarte / das aktuell sichtbare Fragment funktioniert auch. Ich habe es gerade versucht. Hoffe, es gibt keine Fehler.
Skynet
@CommonsWare gibt findFragmentByTagbei ActionBarTabs null zurück . In meiner ActivityErweiterung ActionBarActivityfüge ich zuerst Tabs hinzu ActionBarund finde sie dann!
Muhammad Babar
1
@MuhammadBabar: Sie können versuchen , executePendingTransactions()auf FragmentManagerAufruf nach commit()auf die Transaktion, obwohl ich nicht versucht haben. Oder Sie können setContentView()eine Layoutdatei mit einem <fragment>Tag verwenden. Beides geschieht synchron, sodass das Fragment innerhalb des onCreate()Aufrufs selbst vorhanden ist, in dem Sie executePendingTransaction()oder verwendet haben setContentView(). Andernfalls wird ein Normaler FragmentTransactionasynchron verarbeitet und hat bis zum onCreate()Ende der Zeit noch nicht einmal begonnen .
CommonsWare
110

Versuche dies,

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);

Dies gibt dir das aktuelle Fragment, dann kannst du es mit der Fragmentklasse vergleichen und deine Sachen machen.

    if (currentFragment instanceof NameOfYourFragmentClass) {
     Log.v(TAG, "find the current fragment");
  }
Hammer
quelle
Wo soll diese Zeile gesetzt werden?
Anand Savjani
9
Manchmal muss man getSupportFragmentManager()stattdessen verwenden und wird ohne das supportTeil null
Muz
Entfernen Sie die Anführungszeichen aus "NAME IHRER FRAGMENTKLASSE".
Alan Nelson
37

Ich denke, Sie können das Ereignis onAttachFragment verwenden, um herauszufinden , welches Fragment aktiv ist.

@Override
public void onAttachFragment(Fragment fragment) {
    // TODO Auto-generated method stub
    super.onAttachFragment(fragment);

    Toast.makeText(getApplicationContext(), String.valueOf(fragment.getId()), Toast.LENGTH_SHORT).show();

}
Hede Hodo
quelle
3
Ich kann bekommen, welches Fragment ich angehängt bin. Mein Gedanke ist, wenn ich die Ausrichtung ändere, muss ich dieselbe Ansicht anzeigen, nicht eine andere Ansicht, also wie das geht.
Androi Developer
7
Dies funktioniert nicht, da das aktive Fragment beim Zurückgehen nicht aktualisiert wird.
Justin
1
@ Justin, also müssen wir nur onDetach auch mit einer schwachen Referenzliste verwenden
letroll
12

Ich denke du solltest tun:

Fragment currentFragment = fragmentManager.findFragmentByTag("fragmentTag");

Der Grund dafür ist, dass Sie das Tag "fragmentTag" auf das zuletzt hinzugefügte Fragment setzen (als Sie replace aufgerufen haben).

Niqo
quelle
Danke, ich habe es korrigiert. Es ist ein Tippfehler beim Schreiben dieser Frage. Es wird funktionieren, wenn wir Fragment mit fragmentTransaction.replace gesetzt haben oder fragmentTransaction.addaber nicht bekommen, wenn wir es auf xml gesetzt haben. Siehe meine Bearbeitung 2
Labeeb Panampullan
Ich danke dir sehr! Mein Problem wurde gelöst!
Jonas Gröger
2
Bedeutet diese Lösung nicht, dass Sie dasselbe Tag für mehrere Fragmente setzen müssen? Wie würden Sie sonst wissen, dass fragmentTagdas Tag für das aktuelle Fragment ist?
Thupten
12

Sie können die Liste der Fragmente abrufen und zum letzten schauen.

    FragmentManager fm = getSupportFragmentManager();
    List<Fragment> fragments = fm.getFragments();
    Fragment lastFragment = fragments.get(fragments.size() - 1);

Aber manchmal (wenn Sie zurück navigieren) bleibt die Listengröße gleich, aber einige der letzten Elemente sind null. Also habe ich in der Liste bis zum letzten Nicht-Null-Fragment iteriert und es verwendet.

    FragmentManager fm = getSupportFragmentManager();
    if (fm != null) {
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null) {
            for(int i = fragments.size() - 1; i >= 0; i--){
                Fragment fragment = fragments.get(i);
                if(fragment != null) {
                    // found the current fragment

                    // if you want to check for specific fragment class
                    if(fragment instanceof YourFragmentClass) {
                        // do something
                    }
                    break;
                }
            }
        }
    }
eluleci
quelle
3
Verwenden Sie die getFragments()Methode nicht. Es ist mit gekennzeichnet @hideund sollte nicht in der Unterstützungsbibliothek enthalten sein. Es sollte nicht als Teil der exportierten API betrachtet werden.
James Wald
Heh, dann hätten sie eine Methode erstellen sollen, mit der Sie genau das tun können, was Sie tun getFragments(), weil Sie sie ziemlich oft brauchen. Ich denke, es ist jetzt auch öffentlich verfügbar.
EpicPandaForce
10

Dies ist die einfachste Lösung und Arbeit für mich.

1.) Sie fügen Ihr Fragment hinzu

ft.replace(R.id.container_layout, fragment_name, "fragment_tag").commit();

2.)

FragmentManager fragmentManager = getSupportFragmentManager();

Fragment currentFragment = fragmentManager.findFragmentById(R.id.container_layout);

if(currentFragment.getTag().equals("fragment_tag"))

{

 //Do something

}

else

{

//Do something

}
Gau
quelle
9

Es könnte spät sein, aber ich hoffe, es hilft jemand anderem, auch @CommonsWare hat die richtige Antwort gepostet.

FragmentManager fm = getSupportFragmentManager();
Fragment fragment_byID = fm.findFragmentById(R.id.fragment_id);
//OR
Fragment fragment_byTag = fm.findFragmentByTag("fragment_tag");
Ahmad Ali Nasir
quelle
9
Auf diese Weise können Sie das aktive Fragment nicht abrufen, da Sie die ID oder das Tag nicht unbedingt kennen.
Justin
7

Vielleicht ist der einfachste Weg:

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

Es hat bei mir funktioniert

Madx
quelle
6

Sie können ein Feld in Ihrer übergeordneten Aktivitätsklasse erstellen:

public class MainActivity extends AppCompatActivity {

    public Fragment fr;

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

Und dann in jeder Fragmentklasse:

public class SomeFragment extends Fragment {

@Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        ((MainActivity) getActivity()).fr = this;
}

Ihr 'fr'-Feld ist das aktuelle Fragmentobjekt

Es funktioniert auch mit popBackStack ()

buxik
quelle
4

Ich weiß, dass es eine Weile her ist, aber ich werde dies hier tun, falls es jemandem hilft.

Die mit Abstand richtige Antwort ist (und die ausgewählte) die von CommonsWare. Ich hatte das gleiche Problem wie das folgende

MyFragmentClass fragmentList = 
            (MyFragmentClass) getSupportFragmentManager().findFragmentById(R.id.fragementID);

gab immer wieder null zurück. Mein Fehler war wirklich albern in meiner XML-Datei:

<fragment
    android:tag="@+id/fragementID"
    android:name="com.sf.lidgit_android.content.MyFragmentClass"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

Der Fehler war, dass ich android: tag STATT android: id hatte .

Chayemor
quelle
2

@ Hammer Antwort hat bei mir funktioniert, ich benutze, um eine schwebende Aktionstaste zu steuern

final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View view) {
            android.app.Fragment currentFragment = getFragmentManager().findFragmentById(R.id.content_frame);
            Log.d("VIE",String.valueOf(currentFragment));
            if (currentFragment instanceof PerfilFragment) {
                PerfilEdit(view, fab);
            }
        }
});
Thiago Melo
quelle
2

Wenn Sie von AbstractActivity aus erweitern, können Sie die Methode getFragments () verwenden:

for (Fragment f : getFragments()) {
    if (f instanceof YourClass) {
        // do stuff here
    }
}
Marco Aurélio Alves Puton
quelle
1

Wenn Sie das Fragment in der XML-Ebene der Aktivität definieren, Activitystellen Sie sicher, dass Sie setContentView()vor dem Aufruf aufrufen findFragmentById().

IvancityM
quelle
1

Wenn Sie den BackStack verwenden ... und NUR, wenn Sie den Backstack verwenden, versuchen Sie Folgendes:

rivate Fragment returnToPreviousFragment() {

    FragmentManager fm = getSupportFragmentManager();

    Fragment topFrag = null;

    int idx = fm.getBackStackEntryCount();
    if (idx > 1) {
        BackStackEntry entry = fm.getBackStackEntryAt(idx - 2);
        topFrag = fm.findFragmentByTag(entry.getName());
    }

    fm.popBackStack();

    return topFrag;
}
James Barwick
quelle
0

Dadurch erhalten Sie den aktuellen Fragmentklassennamen ->

String fr_name = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();
Biplob Das
quelle
0
  1. Führen Sie in der onStart-Methode eine Überprüfung durch (welches Fragment im Aktivitätscontainer).

    @Override
    protected void onStart() {
    super.onStart();
    Fragment fragmentCurrent = getSupportFragmentManager.findFragmentById(R.id.constraintLayout___activity_main___container);
    }
  2. Einige überprüfen:

    if (fragmentCurrent instanceof MenuFragment) 
Владислав Шестернин
quelle