4

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

enter image description here

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:

enter image description here

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

enter image description here

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.

AnZyuZya
  • 201
  • 1
  • 3
  • 18

6 Answers6

15

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.

Chandrakanth
  • 3,711
  • 2
  • 18
  • 31
  • YES! Thanks! You made my day :D I've been suffering with it for second evening – AnZyuZya Jan 22 '15 at 12:55
  • 22
    This is not the correct solution, the overlapped Fragment will steal your input events. Thus causing other problems. – WenChao Mar 29 '16 at 05:33
  • I had the same issue and I ended up trying to pop the back stack along with creating a new fragment over top using `getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragmentInstance).addToBackStack( some_name ).commit();` but when I tried to just pop the back stack by name (and NOT creating a new fragment) it seemed to work like a charm for me. PS, I was only going from a fragment back to the fragment that called it. But I figure I'd share my process. – nviens Nov 01 '18 at 17:50
  • @WenChao you can use `android:clickable="true" android:focusable="true"` to overcome the issue. – Mihae Kheel Mar 19 '21 at 15:53
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.

Hiren Patel
  • 52,124
  • 21
  • 173
  • 151
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();
Stephen Lynx
  • 1,077
  • 2
  • 14
  • 29
  • @Chrimson Tulip Nothing changed. I **DO** replace fragment with new one. But when I getting back from `Lessons` to `Catalog` they overlap. When I move vice versa, from `Catalog` to `Lessons` it **DOES** work. It must be some kind of Magic :D – AnZyuZya Jan 22 '15 at 12:40
2

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.

Max Makeichik
  • 227
  • 4
  • 18
0

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.

W.K.S
  • 9,787
  • 15
  • 75
  • 122
0

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

Masum
  • 4,879
  • 2
  • 23
  • 28