Fragments BackStack. Fragments overlap even after pop.

杀马特。学长 韩版系。学妹 提交于 2019-12-21 20:45:55

问题


The problem is to manage properly back stack so the previous fragment is poped out (or deleted). The problem is in their overlapping..

The structure of program as follows:

  • sliding menu with 3 fragments for each section: CatalogFragment, NewsFragment, BlogFragment;
  • each fragment is a listView with items (parsed from JSON);
  • on CatalogFragment's item click I need to replace this CatalogFragment with LessonsFragment, which is list also.

p.s. Items is in russian but I think you can understand

This is how these fragments are added (dynamically):

    @Override
public void onNavigationDrawerItemSelected(int position) {
    FragmentManager fragmentManager = getSupportFragmentManager();
//        fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); //this also doesn't work

    switch (position+1) {
        case 1:
            //getSupportFragmentManager().popBackStack(); // this doesnt work
            fragmentManager.beginTransaction().replace(R.id.container,
                    CatalogFragment.newInstance(position + 1)).addToBackStack("catalog").commit();

            break;
        case 2:
            fragmentManager.beginTransaction().replace(R.id.container,
                    NewsFragment.newInstance(position + 1)).addToBackStack("news").commit();

            break;
        case 3:
            fragmentManager.beginTransaction().replace(R.id.container,
                    BlogFragment.newInstance(position + 1)).addToBackStack("blog").commit();
            break;
    }
}

That's how I replace fragment with new one in onCatalogFragmentInteraction method from interface:

    /** Methods for interaction with list items*/
@Override
public void onCatalogFragmentInteraction(String id){
    //pop previous
    getSupportFragmentManager().popBackStack("catalog", FragmentManager.POP_BACK_STACK_INCLUSIVE);
    //add new
    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.container, LessonsFragment.newInstance());
    fragmentTransaction.addToBackStack("lessons");
    fragmentTransaction.commit();
}

...and that works fine:

But when I move back to fragment from slididng menu fragments overlap.

I belive the problem lies in proper BackStack management but I can't figure out what I did wrong. Another suggestion is that I need to use add/replace somehow better in that case.

I have tried already deleting by name from stack. Maybe needed to delete them by ID?

P.S. Tell if some more code needed. Thanks in advance.


回答1:


I think your all fragments have transparent background or you did not set anything(so default is transparent). So the when you add/replace a fragment above another fragment the below fragment is visible to you. So try to set the background color for every fragment layout.




回答2:


Try to pass only an empty string as the fragment identifier in the addToBackStack.

And instead of

getSupportFragmentManager().popBackStack("catalog", FragmentManager.POP_BACK_STACK_INCLUSIVE

just use

getSupportFragmentManager().popBackStack();



回答3:


<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff"
        android:orientation="vertical" >

</LinearLayout>

I guess this is your xml of fragment, it may be other types of layout (Relative, Frame or other), try to put background color of your parent layout of xml of fragment. For example I put white color for background.




回答4:


I don't think it's perfect solution but this worked for me.

long back_pressed;
@Override
public void onBackPressed()
{
    Log.d(TAG, "HERE WAS PRESSED BACK");
    int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
    final Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_ANSWERS_FRAGMENT);
    if(null != fragment && fragment.isVisible()) {
        Log.d(TAG, "visible");
        showLeaveTest();
    }
    else {
        Log.d(TAG, "invisible");
        if (backStackEntryCount == 0) {
            if (back_pressed + 2000 > System.currentTimeMillis()) super.onBackPressed();
            else try {
                Toast.makeText(this, R.string.double_press, Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                e.printStackTrace();
            }
            back_pressed = System.currentTimeMillis();
        } else {
            getSupportFragmentManager().popBackStack();
            removeCurrentFragment(TAG_RESULT_FRAGMENT);
        }
    }
}

public void removeCurrentFragment(String fragmentTag)
{
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    Fragment currentFrag =  getSupportFragmentManager().findFragmentByTag(fragmentTag);
    String fragName = "NONE";

    if (currentFrag != null)
        fragName = currentFrag.getClass().getSimpleName();

    Log.d(TAG, "flag name " + fragName);

    if (currentFrag != null && currentFrag.isVisible())
        transaction.remove(currentFrag);

    transaction.commit();
}

So, I catch back button press in activity, and, after popping backstack, when fragment overlaps another fragment, this overlapping fragment is visible, so i just remove it with transaction.




回答5:


There is yet another reason that this could happen:

  • You are replacing all fragments into a view with id: R.id.container.

  • Let's say you're pushing a Fragment A whose top-level layout has an id assigned to it e.g. <LinearLayout android:id="@+id/rootLayout">

  • Now any other fragment that you push on to R.id.container will overlap with Fragment A.

So just make sure that the root layout of the fragment that is being pushed does not have an id assigned to it.




回答6:


Just set a background color to your every fragment's parent layout



来源:https://stackoverflow.com/questions/28088600/fragments-backstack-fragments-overlap-even-after-pop

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