webentwicklung-frage-antwort-db.com.de

holen Sie sich das neueste Fragment im Backstack

Wie kann ich die neueste Fragmentinstanz im Backstack hinzufügen (wenn ich das Fragment-Tag und die ID nicht kenne)?

FragmentManager fragManager = activity.getSupportFragmentManager();
FragmentTransaction fragTransacion = fragMgr.beginTransaction();

/****After add , replace fragments 
  (some of the fragments are add to backstack , some are not)***/

//HERE, How can I get the latest added fragment from backstack ??
89
Leem.fin

Sie können die getName()-Methode von FragmentManager.BackStackEntry verwenden, die in API-Ebene 14 eingeführt wurde. Diese Methode gibt ein Tag zurück, das Sie verwendet haben, als Sie das Fragment mit addTobackStack(tag) zum Backstack hinzugefügt haben.

int index = getActivity().getFragmentManager().getBackStackEntryCount() - 1
FragmentManager.BackStackEntry backEntry = getFragmentManager().getBackStackEntryAt(index);
String tag = backEntry.getName();
Fragment fragment = getFragmentManager().findFragmentByTag(tag);

Sie müssen sicherstellen, dass Sie das Fragment wie folgt zum Backstack hinzugefügt haben:

fragmentTransaction.addToBackStack(tag);
144
Deepak Goel
FragmentManager.findFragmentById(fragmentsContainerId) 

function gibt den Link zum Anfang Fragment im Backstack zurück. Anwendungsbeispiel:

    fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer);
            if(fr!=null){
                Log.e("fragment=", fr.getClass().getSimpleName());
            }
        }
    });
46
ashakirov

Ich persönlich habe viele dieser Lösungen ausprobiert und diese funktionierende Lösung erhalten:

Fügen Sie diese Dienstprogrammmethode hinzu, die mehrmals verwendet wird, um die Anzahl der Fragmente in Ihrem Backstack zu ermitteln:

protected int getFragmentCount() {
    return getSupportFragmentManager().getBackStackEntryCount();
}

Wenn Sie dann Ihr Fragment mit der FragmentTransaction-Methode hinzufügen oder ersetzen, generieren Sie ein eindeutiges Tag für Ihr Fragment (z. B. mithilfe der Anzahl der Fragmente in Ihrem Stapel):

getSupportFragmentManager().beginTransaction().add(yourContainerId, yourFragment, Integer.toString(getFragmentCount()));

Schließlich können Sie alle Fragmente in Ihrem Backstack mit dieser Methode finden:

private Fragment getFragmentAt(int index) {
    return getFragmentCount() > 0 ? getSupportFragmentManager().findFragmentByTag(Integer.toString(index)) : null;
}

Das Abrufen des obersten Fragments in Ihrem Backstack kann daher einfach durch Aufruf von erreicht werden:

protected Fragment getCurrentFragment() {
    return getFragmentAt(getFragmentCount() - 1);
}

Hoffe das hilft!

37
ptitvinou

Es gibt eine Liste von Fragmenten im fragmentMananger. Beachten Sie, dass durch das Entfernen eines Fragments die Listengröße nicht verkleinert wird (der Fragmenteintrag wird einfach zu null). Eine gültige Lösung wäre daher:

public Fragment getTopFragment() {
 List<Fragment> fragentList = fragmentManager.getFragments();
 Fragment top = null;
  for (int i = fragentList.size() -1; i>=0 ; i--) {
   top = (Fragment) fragentList.get(i);
     if (top != null) {
       return top;
     }
   }
 return top;
}
6
Erez

Die Antwort von deepak goel funktioniert nicht für mich, da ich immer entry.getName() null bekomme;

Was ich mache, ist ein Tag für das Fragment auf diese Weise zu setzen:

ft.add(R.id.fragment_container, fragmentIn, FRAGMENT_TAG);

Wo ist mein Fragment Transaktion und FRAGMENT_TAG ist das Tag. Dann benutze ich diesen Code, um das Fragment zu erhalten:

Fragment prev_fragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG);
4
Eduardo

diese Hilfsmethode erhält ein Fragment vom Stapelanfang:

public Fragment getTopFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return getSupportFragmentManager().findFragmentByTag(fragmentTag);
}
3

Kotlin

activity.supportFragmentManager.fragments.last()
3

sie können getBackStackEntryAt () verwenden. Um herauszufinden, wie viele Einträge die Aktivität im Backstack enthält, können Sie getBackStackEntryCount () verwenden. 

int lastFragmentCount = getBackStackEntryCount() - 1;
3
Blackbelt

Sieht aus, als hätte sich etwas zum Besseren verändert, weil der folgende Code perfekt für mich funktioniert, aber ich habe ihn nicht in den bereitgestellten Antworten gefunden.

Kotlin:

supportFragmentManager.fragments[supportFragmentManager.fragments.size - 1]

Java:

getSupportFragmentManager().getFragments()
.get(getSupportFragmentManager().getFragments().size() - 1)
2

Habe gerade @roghayeh hosseini (richtige) Antwort genommen und es in Kotlin für die hier 2017 geschafft :)

fun getTopFragment(): Fragment? {
    supportFragmentManager.run {
        return when (backStackEntryCount) {
            0 -> null
            else -> findFragmentByTag(getBackStackEntryAt(backStackEntryCount - 1).name)
        }
    }
}

* Dies sollte aus einer Aktivität heraus aufgerufen werden.

Genießen :)

2
Shirane85

Behalten Sie Ihren eigenen Back-Stack: myBackStack. Da Sie Add ein Fragment zur FragmentManager haben, fügen Sie es auch zu myBackStack hinzu. In onBackStackChanged() pop von myBackStack, wenn seine Länge größer als getBackStackEntryCount ist.

2
Arne Evertsson

Tatsächlich wird dem Stapel kein aktuelles Fragment hinzugefügt, da Sie dem Stapel in einer einzigen Transaktion mehrere oder Fragmente hinzufügen oder Fragmente entfernen können, ohne ein neues hinzuzufügen.

Wenn Sie wirklich einen Stapel von Fragmenten haben möchten und über den Index im Stapel auf ein Fragment zugreifen möchten, sollten Sie eine Abstraktionsebene über der Variable FragmentManager und ihrem Backstack verwenden. So kannst du es machen:

public class FragmentStackManager {
  private final FragmentManager fragmentManager;
  private final int containerId;

  private final List<Fragment> fragments = new ArrayList<>();

  public FragmentStackManager(final FragmentManager fragmentManager,
      final int containerId) {
    this.fragmentManager = fragmentManager;
    this.containerId = containerId;
  }

  public Parcelable saveState() {
    final Bundle state = new Bundle(fragments.size());
    for (int i = 0, count = fragments.size(); i < count; ++i) {
      fragmentManager.putFragment(state, Integer.toString(i), fragments.get(i));
    }
    return state;
  }

  public void restoreState(final Parcelable state) {
    if (state instanceof Bundle) {
      final Bundle bundle = (Bundle) state;
      int index = 0;
      while (true) {
        final Fragment fragment =
            fragmentManager.getFragment(bundle, Integer.toString(index));
        if (fragment == null) {
          break;
        }

        fragments.add(fragment);
        index += 1;
      }
    }
  }

  public void replace(final Fragment fragment) {
    fragmentManager.popBackStackImmediate(
        null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    fragmentManager.beginTransaction()
        .replace(containerId, fragment)
        .addToBackStack(null)
        .commit();
    fragmentManager.executePendingTransactions();

    fragments.clear();
    fragments.add(fragment);
  }

  public void Push(final Fragment fragment) {
    fragmentManager
        .beginTransaction()
        .replace(containerId, fragment)
        .addToBackStack(null)
        .commit();
    fragmentManager.executePendingTransactions();

    fragments.add(fragment);
  }

  public boolean pop() {
    if (isEmpty()) {
      return false;
    }

    fragmentManager.popBackStackImmediate();

    fragments.remove(fragments.size() - 1);
    return true;
  }

  public boolean isEmpty() {
    return fragments.isEmpty();
  }

  public int size() {
    return fragments.size();
  }

  public Fragment getFragment(final int index) {
    return fragments.get(index);
  }
}

Statt Fragmente hinzuzufügen und zu entfernen, indem Sie FragmentManager direkt aufrufen, sollten Sie die Methoden Push(), replace() und pop() von FragmentStackManager verwenden. Sie können auf das oberste Fragment zugreifen, indem Sie einfach stack.get(stack.size() - 1) aufrufen.

Aber wenn Sie Hacks mögen, muss ich andere Wege gehen, um ähnliche Dinge zu tun. Das einzige, was ich erwähnen muss ist, dass diese Hacks nur mit Support-Fragmenten funktionieren.

Der erste Hack ist nur, um alle aktiven Fragmente zum Fragmentmanager hinzuzufügen. Wenn Sie nur Fragmente einzeln ersetzen und aus dem Stapel platzieren, gibt diese Methode das oberste Fragment zurück:

public class BackStackHelper {
  public static List<Fragment> getTopFragments(
      final FragmentManager fragmentManager) {
    final List<Fragment> fragments = fragmentManager.getFragments();
    final List<Fragment> topFragments = new ArrayList<>();

    for (final Fragment fragment : fragments) {
      if (fragment != null && fragment.isResumed()) {
        topFragments.add(fragment);
      }
    }

    return topFragments;
  }
}

Der zweite Ansatz ist Event hackiger und ermöglicht es Ihnen, alle Fragmente der letzten Transaktion hinzuzufügen, für die addToBackStack aufgerufen wurde:

package Android.support.v4.app;

import Java.util.ArrayList;
import Java.util.Collections;
import Java.util.List;

public class BackStackHelper {
  public static List<Fragment> getTopFragments(
      final FragmentManager fragmentManager) {
    if (fragmentManager.getBackStackEntryCount() == 0) {
      return Collections.emptyList();
    }

    final List<Fragment> fragments = new ArrayList<>();

    final int count = fragmentManager.getBackStackEntryCount();
    final BackStackRecord record =
        (BackStackRecord) fragmentManager.getBackStackEntryAt(count - 1);
    BackStackRecord.Op op = record.mHead;
    while (op != null) {
      switch (op.cmd) {
        case BackStackRecord.OP_ADD:
        case BackStackRecord.OP_REPLACE:
        case BackStackRecord.OP_SHOW:
        case BackStackRecord.OP_ATTACH:
          fragments.add(op.fragment);
      }
      op = op.next;
    }

    return fragments;
  }
}

Bitte beachten Sie, dass Sie in diesem Fall diese Klasse in das Android.support.v4.app-Paket einfügen müssen.

1
Michael

Die höchste Antwort (Deepak Goel) funktionierte nicht gut für mich. Irgendwie wurde der Tag nicht richtig hinzugefügt.

Am Ende habe ich nur die ID des Fragments durch den Fluss geschickt (mit Absichten) und es direkt vom Fragmentmanager abgerufen.

0
htafoya

Wenn Sie addToBackStack() verwenden, können Sie folgenden Code verwenden.

List<Fragment> fragments = fragmentManager.getFragments(); activeFragment = fragments.get(fragments.size() - 1);

0
Akbar Kazimov

Oder fügen Sie einfach ein Tag hinzu, wenn Sie Fragmente hinzufügen, die ihrem Inhalt entsprechen, und verwenden Sie ein einfaches statisches String-Feld (Sie können es auch im Aktivitätsinstanzpaket in der Methode onSaveInstanceState (Bundle) speichern), um das zuletzt hinzugefügte Fragment-Tag zu speichern und dieses Fragment durchTag () abzurufen. jederzeit können sie ...