简体   繁体   中英

Navigation view fragments and child backstack

I've handled fragments before but that was with a view pager and tablayout and I was able to keep the fragments state by building an array and returning a frag from that array.

but now using fragment manager, I have access to add and replace, but both create new instances of my fragments without saving what has occured (ie typing on editText).

How can I keep or reuse the fragments I've created when navigating from the menu (keep in mind some of these fragments will have a child backstack, the back button should only take you out of deep fragments not my main ones)

current code

 private void initNavigation(){
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    /* Initialize fragments for navigation drawer */
    fragments = new Fragment[]{
            new ProfileFragment(),
            new StatsFragment()};

    /* Set selection of navigation item */
    nav_view = (NavigationView) findViewById(R.id.nav_view);
    nav_view.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    item.setChecked(true);

                    FragmentManager fragmentManager = getSupportFragmentManager();
                    switch (item.getItemId()) {
                        case R.id.nav_routine:
                            if(fragmentManager.findFragmentByTag("TAG0") != null){
                                Log.i("fm", "reloading profile frag");
                                fragmentManager.beginTransaction().replace(R.id.content_main,
                                        fragmentManager.findFragmentByTag("TAG0"), "TAG0");
                            } else{
                                fragmentManager.beginTransaction().replace(R.id.content_main, fragments[0], "TAG0").commit();
                            }
                            break;
                       default:
                           if(fragmentManager.findFragmentByTag("TAG1") != null){
                               Log.i("fm", "reloading stats frag");
                               fragmentManager.beginTransaction().replace(R.id.content_main,
                                       fragmentManager.findFragmentByTag("TAG1"), "TAG1");
                           } else{
                               fragmentManager.beginTransaction().replace(R.id.content_main, fragments[1], "TAG1").commit();
                           }
                           break;
                   }

                   drawerLayout.closeDrawers();
                   return true;
               }
           }
    );
}

Edit solved:

I found out that in order for a view to be saved it must have an ID (makes sense). Also I wasn't using .commit() with some of my .replace in my prior code

nav_view.setNavigationItemSelectedListener(
             new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    item.setChecked(true);

                    FragmentManager fragmentManager = getSupportFragmentManager();
                    switch (item.getItemId()) {
                        case R.id.nav_routine:
                                fragmentManager.beginTransaction().replace(R.id.content_main, fragments[0], "TAG0").commit();
                            break;
                       default:
                               fragmentManager.beginTransaction().replace(R.id.content_main, fragments[1], "TAG1").commit();
                           break;
                   }

                   drawerLayout.closeDrawers();
                   return true;
               }
           }
    );

Im not clear with your question .But this is how keeping backState of fragments.

Fragment mfragment=new Fragmentname();           

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.fragment_container, mfragment);
        String backStateName = mfragment.getClass().getName();
        if (position != 0) {
            ft.addToBackStack(backStateName);
        }

        ft.commit();

As you could save the data of a Fragment when leaving from it I think you already know about SavedInstanceState . Anyway, while you're transacting one fragment to another from your Activity using fragment transaction, you need to add addToBackStack(null) before your commit. So the transaction should look like

fragmentManager.beginTransaction().replace(R.id.content_main, fragments[0], "TAG0").addToBackStack(null).commit();

And override the onBackPressed function of your Activity like this.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM