Fragment保存状态

Fragment保存状态


http://stackoverflow.com/questions/11353075/how-can-i-maintain-fragment-state-when-added-to-the-back-stack

If you return to a fragment from the back stack it does not re-create the fragment but re-uses the same instance and starts with onCreateView() in the fragment lifecycle, see Fragment lifecycle.

So if you want to store state you should use instance variables and not rely on onSaveInstanceState().

一种解决方式:

I guess there is an alternative way to achieve what you are looking for. I dont say its a complete solution but it served the purpose in my case.

What i did is instead of replacing the fragment i just added target fragment. So basically you will going to use add() method instead replace().

What else i did. I hide my current fragment and also add it to backstack.

Hence it overlaps new fragment over the current fragment without destroying its view.(check that its onDestroyView() method is not being called.Plus adding it to backstate gives me advantage of resuming the fragment.

Here is the code :

            Fragment fragment=new DestinationFragment();
            FragmentManager fragmentManager = getFragmentManager();
            android.app.FragmentTransaction ft=fragmentManager.beginTransaction();
            ft.add(R.id.content_frame, fragment);
            ft.hide(SourceFragment.this);
            ft.addToBackStack(SourceFragment.class.getName());
            ft.commit();


AFAIK System only calls onCreateView if the view is destroyed or not created. But here we have saved the view by not removing it from memory.So it will not create new view.

And when you get back from Destination Fragment it will pop the last FragmetnTransaction removing top fragment which will make the topmost(SourceFragment's) view to appear over screen.

COMMENT :As i said it is not a complete solution as it doesnt remove the view of Source fragment and hence occupying more memory than usual.But still serve the purpose.Also we are using a totally different mechanism of hiding view instead of replacing it which is non traditional.

So its not really for how you maintain the state,but for how you maintain the view.


另外一种解决方式:


http://stackoverflow.com/questions/15313598/once-for-all-how-to-correctly-save-instance-state-of-fragments-in-back-stack

public final class MyFragment extends Fragment {
    private TextView vstup;
    private Bundle savedState = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.whatever, null);
        vstup = (TextView)v.findViewById(R.id.whatever);

        /* (...) */

        /* If the Fragment was destroyed inbetween (screen rotation), we need to recover the savedState first */
        /* However, if it was not, it stays in the instance from the last onDestroyView() and we don't want to overwrite it */
        if(savedInstanceState != null && savedState == null)
            savedState = savedInstanceState.getBundle(App.STAV);
        if(savedState != null)
            vstup.setText(savedState.getCharSequence(App.VSTUP));
        savedState = null;

        return v;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        savedState = saveState(); /* vstup defined here for sure */
        vstup = null;
    }

    private Bundle saveState() { /* called either from onDestroyView() or onSaveInstanceState() */
        Bundle state = new Bundle();
        state.putCharSequence(App.VSTUP, vstup.getText());
        return state;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        /* If onDestroyView() is called first, we can use the previously savedState but we can't call saveState() anymore */
        /* If onSaveInstanceState() is called first, we don't have savedState, so we need to call saveState() */
        /* => (?:) operator inevitable! */
        outState.putBundle(App.STAV, savedState != null ? savedState : saveState());
    }

    /* (...) */

}


通过Activity保存Fragment状态

http://stackoverflow.com/questions/15608709/using-onsaveinstancestate-with-fragments-in-backstack

It is possible that your member variables don't exist anymore because the FragmentManager in your Activity is dying with all of your fragments.

You need to override the method onSaveInstanceState of your Activity class as well, because you need to save the Activity state before you save the Fragments state.

As the documentation says:

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.

UPDATE

In your Activity onSaveInstanceState and onRestoreInstanceState, try saving you Fragment references and then restore them with something like this:

public void onSaveInstanceState(Bundle outState){
    getFragmentManager().putFragment(outState,"myfragment",myfragment);
}
public void onRetoreInstanceState(Bundle inState){
    myFragment = getFragmentManager().getFragment(inState,"myfragment");
}

Tell me then if you had luck! :-)


另外一种方式:

http://curioustechizen.blogspot.com/2014/02/nested-fragments-and-backstack-part-3.html

    @Override
    public void onPause() {
        super.onPause();
        ((NestedFragApp)getActivity().getApplication()).setFragmentSavedState(SAVED_STATE_KEY, getFragmentManager().saveFragmentInstanceState(this));
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ((NestedFragApp)getActivity().getApplication()).setFragmentSavedState(SAVED_STATE_KEY, null);
    }

public static ContainerFragment newInstance(SavedState savedState) {
        ContainerFragment frag = new ContainerFragment();
        frag.setInitialSavedState(savedState);
        return frag;
    }
    ...
    ...
    @Override
    public void onPause() {
        super.onPause();
        ((NestedFragApp)getActivity().getApplication()).setFragmentSavedState(SAVED_STATE_KEY, getFragmentManager().saveFragmentInstanceState(this));
    }



你可能感兴趣的:(android)