Android Fragment Back Stack

2019-06-15 07:21发布

问题:

I have used multiple Fragments in my Project. I want to save a Fragment's state and restore this state when I come back to this. In this Fragment I show multiple images which change on button click. I use the following code for this:

String backStateName = fragment.getClass().getName();
FragmentManager fragmentManager = getSupportFragmentManager();
boolean fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
 fragmentTransaction.replace(R.id.container_body, fragment);
 fragmentTransaction.addToBackStack(backStateName);
 fragmentTransaction.commit();
}

It works fine & it saves state, but it does not show previous image's.

Any help, suggestion or tutorials would be highly appreciated. Thank you.

回答1:

I am trying with the fragment list ....

Initilize the framents list

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

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();

            }
        }
    });


回答2:

You can use the following code. It will not reload the fragment when you come back from previous fragment:

    if (!fragmentPopped) {
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
     fragmentTransaction.hide(getFragmentManager().findFragmentById(R.id.container_body));
     fragmentTransaction.add(R.id.container_body, fragment);
     fragmentTransaction.addToBackStack(backStateName);
     fragmentTransaction.commit();
    }


回答3:

You can use

fragmentTransaction.hide(getFragmentManager().findFragmentById(R.id.frame_container));
fragmentTransaction.add(R.id.frame_container, fragment);
fragmentTransaction.addToBackStack(null);

Instead of

fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(backStateName);


回答4:

If you can save the images in the android disk cache when you open the fragment and display the images by reading from the disk cache it might resolve your problem. Follow the below link from google on how to save images in disk cache.

https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

Below are the steps i think you should follow.

  1. Store your images in the disk cache.
  2. onAttaching your ImagesFragment to the Activity read the images from the disk cache and show them
  3. when the fragment is popped from the backstack your code will automatically read the images from the disk cache.

Hope this helps.



回答5:

I used multiple fragments with this code.Put this code in your MainActivity where's your framelayout or fragment.

@Override    
public void onBackPressed() {
  /*  Fragment fragment = new SettingActivity();
    String title = getString(R.string.app_name);
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.container_body, fragment);
    fragmentTransaction.commit();
    // set the toolbar title
    getSupportActionBar().setTitle(title);*/
    //Log.e("title:", getTitle().toString());
    getSupportActionBar().setTitle("Home");
    //Log.e("title:", getTitle().toString());
    if (!getTitle().toString().equals("Home")) {

        Fragment fragment = new Activity_category();
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container_body, fragment).commit();
        this.setTitle("Home");
    } else {

        super.onBackPressed();

    }
}

May this will help you.



回答6:

You taking your fragment in back stack so its didn't fault of your fragment you need to check in your image library. May i know which library are you using. I recommended to use picasso library. I am also using this and getting state saved image in my fragment.

http://square.github.io/picasso/



回答7:

You can do circular navigation by using below code. You can visit even two fragments as vice-versa by endless.

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
     hideLastFragment(fragmentTransaction);
     fragmentTransaction.add(R.id.profile_fragmentContainer, youfFragment, fragmentTagName).addToBackStack(fragmentTagName);
     fragmentTransaction.commitAllowingStateLoss();

    /**
         * To hide the last fragment
         *
         * @param fragmentTransaction FragmentTransaction
         */
        public void hideLastFragment(FragmentTransaction fragmentTransaction) {
            final int backStackCount = getSupportFragmentManager().getBackStackEntryCount() - 1;
            if (backStackCount >= 0) {
                String fragmentName = getSupportFragmentManager().getBackStackEntryAt(backStackCount).getName();
                Fragment lastFragment = getSupportFragmentManager().findFragmentByTag(fragmentName);
                fragmentTransaction.hide(lastFragment);
            }
        }