سؤال

I've found a number of questions that are similar, but I haven't found any answers that seems to fit my specific case

What is the proper way of iterating through all of the fragments on the backstack, in order to perform a specific operation on each of them? I need to update some and remove some of the fragments, based on changes in the environment (I could, theoretically, trap an event when the fragment receives focus again and take appropriate action then, but this would complicate things a bit, as I'm also dealing with things getting renamed)

Given that the container for the fragments is as follows:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:id="@+id/fragment_container"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent" />

And adding fragments as follows:

FragmentTransaction transaction = context.getSupportFragmentManager().beginTransaction();
Fragment fragment = new CustomFragment();

transaction.add(R.id.fragment_container, fragmentBase);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.addToBackStack(nameOfFragment);

transaction.commit();

context.getSupportFragmentManager().executePendingTransactions();

My first attempt to iterate was:

getSupportFragmentManager().executePendingTransactions();
for (int indexFragment = 0; indexFragment < getSupportFragmentManager().getBackStackEntryCount(); indexFragment++)
{
    FragmentManager.BackStackEntry backStackEntry = getSupportFragmentManager().getBackStackEntryAt(indexFragment);                    

    // If Android keeps the ID, surely there should be a way of getting to the actual fragment itself, from that ID?
    Fragment fragment = getSupportFragmentManager().findFragmentById(backStackEntry.getId());                   

    if (fragment != null)
    {               
        //TODO: Cast the fragment and perform some transactions against it

        // We never get here; as fragment is always null
    }
}

From a different angle:

FrameLayout frameLayout = (FrameLayout)findViewById(R.id.fragment_container);

for (int indexFrameLayout = 0; indexFrameLayout < frameLayout.getChildCount(); indexFrameLayout++)
{
    View view = (View)frameLayout.getChildAt(indexFrameLayout);

    // I get the right number of views; but I can't interact with them as fragments
}

I could, hypothetically, hack my way past this issue by keeping references to the fragments, but there are problems with that approach.

  • Is there a way that I can get to the fragments that are currently on the backstack?

  • Given the assumption that I can get to a fragment, is there a way of removing it (and it alone) from somewhere within the backstack? (There is the transaction.remove method, but was that intended to work on fragments sitting in the middle of the back stack?)

Thanks

هل كانت مفيدة؟

المحلول

BackStackEntry is not necessary associated with single Fragment, it represents a FragmentManager state, you may have a bunch of fragments in a transaction and therefore a bunch of fragments in a state. Use this flavor of add() method and assign an unique id to your fragments via tag. Then you'll be able to find them via getSupportFragmentManager().findFragmentById(fragment_tag);

As for your task, afaik there's no way to remove an arbitrary state from BackStack, your only choice is to pop stack removing one state after the other from the top. So you can, for example, override your onBackPressed() and call fragmentManager.popBackStack() to simply go to the previous state or fragmentManager.popBackStack(backstack_tag) to skip some states and go where you need to.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top