Prevent The Same Fragment From Stacking More Than Once ( addToBackStack)

◇◆丶佛笑我妖孽 提交于 2019-11-30 19:53:17
Abu Ruqaiyah

From How to resume Fragment from BackStack if exists, which maybe very similar to your query.

There is a way to pop the back stack based on either the transaction name or the id provided by commit (for eg. using the Fragment's class name as Thijs already mentioned):

String backStateName = fragment.getClass().getName();

Adding to backstack:

FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();

When popping:

getSupportFragmentManager().popBackStackImmediate (backStateName, 0); 

So before replacing fragment, we can check existance in backstack like:

boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);

if (!fragmentPopped){ //fragment not in back stack, create it.
    ...
    ...
    ft.addToBackStack(backStateName);
    ft.commit();
}

Please check the above question and the accepted answer for more explanation.

I have solved one of your questions, namely how can I prevent it from stacking on to it self?, in one of my own projects a while ago. This was the exact code I used there:

public void setContent(@NonNull Fragment fragment, boolean addToBackStack) {
    Fragment current = getSupportFragmentManager().findFragmentById(R.id.main_content);
    if (current == null || !current.getClass().equals(fragment.getClass())) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (addToBackStack) {
            transaction.addToBackStack(null).add(R.id.main_content, fragment).commit();
        } else {
            transaction.replace(R.id.main_content, fragment).commit();
        }
    }
}

What this code does is checks of what class the currently showing Fragment is and compare that to the fragment you want to replace it with. If they are the same, it doesn't do anything. This code can be shaped to fit your needs like so

Fragment newFragment = new FragmentB(); //OR FragmentC
Fragment current = getSupportFragmentManager().findFragmentById(R.id.activity2_layout);
if (!current.getClass().equals(newFragment.getClass())) {

    //POP BACKSTACK HERE LIKE EXPLAINED BELOW

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    final String tag = newFragment.getClass().getSimpleName();
    transaction.addToBackStack(tag);
    transaction.add(R.id.activity2_layout, newFragment, tag);
    transaction.commit();
} else {
    //THROW AN ERROR OR SOMETHING, HANDLE IT BEING THE SAME
}

Making sure that only one fragment of a certain type is present at a time could probably be achieved by popping the backstack until before the first occurence of the same fragment. I have not written any code for this but it shouldn't be too difficult to implement that feature. If you can't figure it out yourself, let me know and I will try to write you an example :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!