Listview fragment is getting recreated on pressing backbutton

和自甴很熟 提交于 2019-12-03 17:31:51

You have multiple options to rectify this issue.

  1. Override onSaveInstanceState like this:

    @Override
    public void onSaveInstanceState (Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("mIsBackbuttonisPressed", mIsBackbuttonisPressed);
    }
    

    and then in your onCreateView you can get your variable back by:

    if (savedInstanceState != null)
        mIsBackbuttonisPressed = savedInstanceState.getBoolean("mIsBackbuttonisPressed", false);
    
  2. You can set this.setRetainInstance(true); in your onCreate method of your fragment.

If you could post your Activity code with creates your fragment I can also tell you other options. (P.S I cannot write it as a comment so posting it in the answer.)

instead of

t.replace(R.id.id_tfragment, mTFragment); 

use

t.add(R.id.id_tfragment, mTFragment); 

It worked for me

I don't think that the accepted answer is right because Fragment.onSaveInstanceState will not be called until the activity hosting it needs to save its state: The docs states:

There are many situations where a fragment may be mostly torn down (such as when placed on the back stack with no UI showing), but its state will not be saved until its owning activity actually needs to save its state.

In other words: if you're using a Activity with multiple fragments for each screen (which is very common), the fragment state will not be saved when you move the next screen.

You also can't use Fragment.setRetainInstance because he's meant only to fragments that aren't on the back stack.

Most of the time, you don't have to think about this but sometimes it's important. Like when you have scrolled a list and want to "remember" the scroll location.

I took a long time to realize that the fragments put on the back stack are kind of saved and you can reuse the view that you already created instead of creating one every time the fragment calls onCreateView. My setup is something like this:

public abstract class BaseFragment extends Fragment {
     private boolean mSaveView = false;
     private SoftReference<View> mViewReference;

     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          if (mSaveView) {
               if (mViewReference != null) {
                    final View savedView = mViewReference.get();
                    if (savedView != null) {
                         if (savedView.getParent() != null) {
                              ((ViewGroup) savedView.getParent()).removeView(savedView);
                              return savedView;
                         }
                    }
               }
          }

          final View view = inflater.inflate(getFragmentResource(), container, false);
          mViewReference = new SoftReference<View>(view);
          return view;
     }

     protected void setSaveView(boolean value) {
           mSaveView = value;
     }
}

public class MyFragment extends BaseFragment {
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          setSaveView(true);
          final View view = super.onCreateView(inflater, container, savedInstanceState);
          ListView placesList = (ListView) view.findViewById(R.id.places_list);
          if (placesList.getAdapter() == null) { // this check is important so you don't restart your adapter
               placesList.setAdapter(createAdapter());
          }
     }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!