3

I am working on single activity based principle. But I am facing a problem when the same fragment is open again because its again adds in fragment backstack entry. So backstack contains multiple backstack entries for same fragment. This creates problem on back navigation.

Example :- A|B|C|D|A|C|A

So when I press back key same fragment is displaying multiple times. Is there any way to reuse the existing fragment from backstack entry.

I am managing my backstack like this :-

fragmentManager.beginTransaction().setCustomAnimations(R.anim.fragment_enter,
                        R.anim.fragment_exit, R.anim.pop_enter, R.anim.pop_exit).
                        add(R.id.frameLayout, fragment).addToBackStack(backStateName).commit(); 

Any kind of help will be appreciated.

Linh
  • 57,942
  • 23
  • 262
  • 279
Chandan Wadhwa
  • 196
  • 2
  • 13

4 Answers4

1
private void createOrResumeFragment(String fragmentTag){
  FragmentManager manager = getSupportFragmentManager();
  FragmentTransaction ft = manager.beginTransaction();
  boolean fragmentPopped = manager.popBackStackImmediate (fragmentTag, 0);
  Fragment fragment = manager.findFragmentByTag(fragmentTag);
    if(!fragmentPopped && fragment == null){   
      //Create an new instance if it is null and add it to stack 
       fragment = new MyFragment();
       ft.addToBackStack(fragmentTag);
    }
    ft.replace(R.id.framelayout, fragment); 
    ft.commit();
}
Rajan Kali
  • 12,627
  • 3
  • 25
  • 37
1

Trying this using the fragment list

See the Answer Here

Initialize the fragments list

  static List<String> fragments = new ArrayList<String>();

on Start of first fragment on Activity add this

 if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction().replace(R.id.frame, new AFragment()).commit();
        fragments.add("package.fragment.AFragment");
    }

Code to fragment change and take in back stack

   String backStateName = fragment.getClass().getName();
    FragmentManager manager = getSupportFragmentManager();
    //fragment not in back stack, create it.
    FragmentTransaction ft = manager.beginTransaction();
    if(!fragments.contains(backStateName)) {

       // ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        // ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
        ft.replace(R.id.frame, fragment);
        ft.addToBackStack(backStateName);
        ft.commit();

        fragments.add(backStateName);
        System.out.println("backStateName" + fragments);
    }
    else
    {


        ft.replace(R.id.frame, fragment);
        ft.commit();

    }

onBackpressed

 @Override
public void onBackPressed() {
    if(fragments.size()>0)
        {
            fragments.remove(fragments.size()-1);
        }
        super.onBackPressed();
}

for back remove stack

 final android.app.FragmentManager fm = getFragmentManager();

    fm.addOnBackStackChangedListener(new android.app.FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {

            if (getSupportFragmentManager().getBackStackEntryCount() ==0) {
               // dLayout.closeDrawers();
                finish();
            }
            else
            {
               // dLayout.closeDrawers();

            }
        }
    });
Community
  • 1
  • 1
Arjun saini
  • 4,223
  • 3
  • 23
  • 51
0

Before adding or replacing the fragment on backstack, check that if the fragment already in backstack or not.

boolean fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
if (fragmentPopped) {
   // fragment is popped from backStack
} else {
  // add or replace your fragment here      
}
Deepak Goyal
  • 4,747
  • 2
  • 21
  • 46
0
public void changeFragment(Fragment fragment) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    Fragment currentVisibleFragment = fragmentManager.findFragmentById(R.id.container);

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.container, fragment, fragment.getClass().getSimpleName());
    if (!currentVisibleFragment.getClass().getSimpleName().trim().equalsIgnoreCase(fragment.getClass().getSimpleName().trim())) {
    for (int i = fragmentManager.getBackStackEntryCount() - 1; i > 0; i--) {
        if (fragmentManager.getBackStackEntryAt(i).getName().equalsIgnoreCase(fragment.getClass().getSimpleName())) {
            fragmentManager.popBackStack(fragmentManager.getBackStackEntryAt(i).getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
        }
    }

    fragmentTransaction.addToBackStack(fragment.getClass().getSimpleName());
    } else {
        fragmentManager.popBackStack();
        fragmentTransaction.addToBackStack(fragment.getClass().getSimpleName());
    }
    fragmentTransaction.commit();
}


boolean doubleBackToExitPressedOnce = false;

@Override
public void onBackPressed() {
    if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        super.onBackPressed();
    } else {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            finish();
            return;
        }

        this.doubleBackToExitPressedOnce = true;
        Toast.makeText(this, "Are you sure you want to exit?", Toast.LENGTH_SHORT).show();

        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                doubleBackToExitPressedOnce = false;
            }
        }, 2000);
    }
}

Call the method to replace fragment with single entry in backstack

changeFragment(new YourFragmentClassName());

Ketan Ramani
  • 4,874
  • 37
  • 42