How to keep only one instance of a fragment, when switching with NavigationDrawer?

后端 未结 4 407

My App starts with a AddressFragment. From the NavigationDrawer I start (amongst others) a new AddressFragment with:

getSupportFragmentManag         


        
相关标签:
4条回答
  • 2020-12-05 15:54

    Step one:

    Optimize current code to allow a Fragment to have his own "TAG"

    getSupportFragmentManager().beginTransaction()
                    .replace(R.id.container, new AddressFragment())
                    .addToBackStack(**AddressFragment.class.getName()**)
                    .commit();
    

    Step two:

    Somewhere in your application flow you will need to determine if a fragment exists:

    public static boolean isFragmentInBackstack(final FragmentManager fragmentManager, final String fragmentTagName) {
        for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) {
            if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) {
                return true;
            }
        }
        return false;
    }
    

    Step three:

    perform fragment action

    if (exists) {
        // Fragment exists, go back to that fragment
        //// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow
        mFragmentManager.popBackStackImmediate(AddressFragment.class.getName(), 0);
    
    } else {
        // Fragment doesn't exist
        // STEP 1 + additional backstack management
    }
    
    0 讨论(0)
  • 2020-12-05 16:02

    This is tested answer, Hope this will help you First Make these field globally in MainActivity

    private static final int TIME_INTERVAL = 2000; 
    private long mBackPressed;
    private FragmentManager fm;
    private FragmentTransaction ft;
    private DrawerLayout drawer;
    

    Now in onNavigationItemSelected() implement like that

        @Override
    public boolean onNavigationItemSelected(MenuItem item) {
    Fragment fragment = null;
    Class fragmentClass = null;
    switch (item.getItemId()) {
    case R.id.nav_home:
    fragmentClass = Fragment.class;//this is MainAvctivty extends AppCompatActivity
    break;
    case R.id.nav_f1:
    fragmentClass = FragmentOne.class;
    break;
    case R.id.nav_f2:
    fragmentClass = FragmentTwo.class;
    break;
    case R.id.nav_f3:
    fragmentClass = FragmentThree.class;
    break;
    case R.id.nav_f4:
    fragmentClass = FragmentFour.class;
    break;
    case R.id.nav_f5:
    fragmentClass = FragmentFive.class;
    break;
    default:
    fragmentClass = Fragment.class;
    }
    try {
    fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {e.printStackTrace();}
    //Insert the fragment by replacing any existing fragment
    fm = getSupportFragmentManager();
    ft = fm.beginTransaction();
    ft.replace(R.id.frame_container, fragment);
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.addToBackStack(null);
    ft.commit();
    item.setChecked(true);
    setTitle(item.getTitle());
    drawer.closeDrawers();
    return true;
    }
    

    Now handle onbackpressed like below

    @Override
    public void onBackPressed() {
    if (drawer != null) {
    fm = getSupportFragmentManager();
    ft = fm.beginTransaction();
    if (drawer.isDrawerOpen(GravityCompat.START)) {
    drawer.closeDrawer(GravityCompat.START);
    } else if (fm.getBackStackEntryCount() > 0) {
    fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
    ft.commit();
    } else if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) {
    super.onBackPressed();
    } else {
    Toast.makeText(this,"Press again to exit the app",Toast.LENGTH_SHORT).show();
    }
    mBackPressed = System.currentTimeMillis();
    }
    }
    
    0 讨论(0)
  • 2020-12-05 16:06

    First time you create the fragment with a tag.

    When you want to replace it try to get the fragment with tag and if it return null you create a new one

    0 讨论(0)
  • 2020-12-05 16:20

    When creating the fragment set a tag for it, then later you can find it through the fragment manager and replace/create accordingly.

    FragmentManager fManager = getFragmentManager();
    FragmentTransaction fTransaction = fManager.beginTransaction();
    Fragment fragment = fManager.findFragmentByTag("uniqueTag");
    
    // If fragment doesn't exist yet, create one
    if (fragment == null) {
        fTransaction.add(R.id.fragment_list, new ListFrag(), "uniqueTag");
    }
    else { // re-use the old fragment
        fTransaction.replace(R.id.fragment_list, fragment, "uniqueTag");
    }
    
    0 讨论(0)
提交回复
热议问题