How to correctly save instance state of Fragments in back stack?

后端 未结 6 1269
小鲜肉
小鲜肉 2020-11-21 11:57

I have found many instances of a similar question on SO but no answer unfortunately meets my requirements.

I have different layouts for portrait and landscape and I

6条回答
  •  [愿得一人]
    2020-11-21 12:23

    Thanks to DroidT, I made this:

    I realize that if the Fragment does not execute onCreateView(), its view is not instantiated. So, if the fragment on back stack did not create its views, I save the last stored state, otherwise I build my own bundle with the data I want to save/restore.

    1) Extend this class:

    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    
    public abstract class StatefulFragment extends Fragment {
    
        private Bundle savedState;
        private boolean saved;
        private static final String _FRAGMENT_STATE = "FRAGMENT_STATE";
    
        @Override
        public void onSaveInstanceState(Bundle state) {
            if (getView() == null) {
                state.putBundle(_FRAGMENT_STATE, savedState);
            } else {
                Bundle bundle = saved ? savedState : getStateToSave();
    
                state.putBundle(_FRAGMENT_STATE, bundle);
            }
    
            saved = false;
    
            super.onSaveInstanceState(state);
        }
    
        @Override
        public void onCreate(Bundle state) {
            super.onCreate(state);
    
            if (state != null) {
                savedState = state.getBundle(_FRAGMENT_STATE);
            }
        }
    
        @Override
        public void onDestroyView() {
            savedState = getStateToSave();
            saved = true;
    
            super.onDestroyView();
        }
    
        protected Bundle getSavedState() {
            return savedState;
        }
    
        protected abstract boolean hasSavedState();
    
        protected abstract Bundle getStateToSave();
    
    }
    

    2) In your Fragment, you must have this:

    @Override
    protected boolean hasSavedState() {
        Bundle state = getSavedState();
    
        if (state == null) {
            return false;
        }
    
        //restore your data here
    
        return true;
    }
    

    3) For example, you can call hasSavedState in onActivityCreated:

    @Override
    public void onActivityCreated(Bundle state) {
        super.onActivityCreated(state);
    
        if (hasSavedState()) {
            return;
        }
    
        //your code here
    }
    

提交回复
热议问题