Fragment保存状态

来源:互联网 发布:苹果隐藏图标软件 编辑:程序博客网 时间:2024/05/22 14:40

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 withonCreateView() in the fragment lifecycle, see Fragment lifecycle.

So if you want to store state you should use instance variables andnot 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 useadd() 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 itsonDestroyView() method is not being called.Plus adding it tobackstate 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 lastFragmetnTransaction 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));    }



0 0
原创粉丝点击