am b46ed763
: Add new Fragment API for explicitly saving/restoring state.
* commit 'b46ed7636be9341b6ce0b158b3d86f34a437e6da': Add new Fragment API for explicitly saving/restoring state.
This commit is contained in:
@ -30627,6 +30627,19 @@
|
|||||||
<parameter name="hasMenu" type="boolean">
|
<parameter name="hasMenu" type="boolean">
|
||||||
</parameter>
|
</parameter>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="setInitialSavedState"
|
||||||
|
return="void"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="state" type="android.app.Fragment.SavedState">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
<method name="setRetainInstance"
|
<method name="setRetainInstance"
|
||||||
return="void"
|
return="void"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
@ -30718,6 +30731,53 @@
|
|||||||
</parameter>
|
</parameter>
|
||||||
</constructor>
|
</constructor>
|
||||||
</class>
|
</class>
|
||||||
|
<class name="Fragment.SavedState"
|
||||||
|
extends="java.lang.Object"
|
||||||
|
abstract="false"
|
||||||
|
static="true"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<implements name="android.os.Parcelable">
|
||||||
|
</implements>
|
||||||
|
<method name="describeContents"
|
||||||
|
return="int"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</method>
|
||||||
|
<method name="writeToParcel"
|
||||||
|
return="void"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="dest" type="android.os.Parcel">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="flags" type="int">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
|
<field name="CREATOR"
|
||||||
|
type="android.os.Parcelable.ClassLoaderCreator"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
|
</class>
|
||||||
<class name="FragmentBreadCrumbs"
|
<class name="FragmentBreadCrumbs"
|
||||||
extends="android.view.ViewGroup"
|
extends="android.view.ViewGroup"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
@ -31151,6 +31211,19 @@
|
|||||||
<parameter name="listener" type="android.app.FragmentManager.OnBackStackChangedListener">
|
<parameter name="listener" type="android.app.FragmentManager.OnBackStackChangedListener">
|
||||||
</parameter>
|
</parameter>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="saveFragmentInstanceState"
|
||||||
|
return="android.app.Fragment.SavedState"
|
||||||
|
abstract="true"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="f" type="android.app.Fragment">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
<field name="POP_BACK_STACK_INCLUSIVE"
|
<field name="POP_BACK_STACK_INCLUSIVE"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
@ -150858,6 +150931,31 @@
|
|||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
</interface>
|
</interface>
|
||||||
|
<interface name="Parcelable.ClassLoaderCreator"
|
||||||
|
abstract="true"
|
||||||
|
static="true"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<implements name="android.os.Parcelable.Creator">
|
||||||
|
</implements>
|
||||||
|
<method name="createFromParcel"
|
||||||
|
return="T"
|
||||||
|
abstract="true"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="source" type="android.os.Parcel">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="loader" type="java.lang.ClassLoader">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
<interface name="Parcelable.Creator"
|
<interface name="Parcelable.Creator"
|
||||||
abstract="true"
|
abstract="true"
|
||||||
static="true"
|
static="true"
|
||||||
|
@ -1875,7 +1875,7 @@ public final class ActivityThread {
|
|||||||
}
|
}
|
||||||
deliverNewIntents(r, intents);
|
deliverNewIntents(r, intents);
|
||||||
if (resumed) {
|
if (resumed) {
|
||||||
mInstrumentation.callActivityOnResume(r.activity);
|
r.activity.performResume();
|
||||||
r.activity.mTemporaryPause = false;
|
r.activity.mTemporaryPause = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2831,7 +2831,7 @@ public final class ActivityThread {
|
|||||||
}
|
}
|
||||||
deliverResults(r, res.results);
|
deliverResults(r, res.results);
|
||||||
if (resumed) {
|
if (resumed) {
|
||||||
mInstrumentation.callActivityOnResume(r.activity);
|
r.activity.performResume();
|
||||||
r.activity.mTemporaryPause = false;
|
r.activity.mTemporaryPause = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,6 +449,51 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
|
|||||||
boolean mLoadersStarted;
|
boolean mLoadersStarted;
|
||||||
boolean mCheckedForLoaderManager;
|
boolean mCheckedForLoaderManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State information that has been retrieved from a fragment instance
|
||||||
|
* through {@link FragmentManager#saveFragmentInstanceState(Fragment)
|
||||||
|
* FragmentManager.saveFragmentInstanceState}.
|
||||||
|
*/
|
||||||
|
public static class SavedState implements Parcelable {
|
||||||
|
final Bundle mState;
|
||||||
|
|
||||||
|
SavedState(Bundle state) {
|
||||||
|
mState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedState(Parcel in, ClassLoader loader) {
|
||||||
|
mState = in.readBundle();
|
||||||
|
if (loader != null && mState != null) {
|
||||||
|
mState.setClassLoader(loader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeBundle(mState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.ClassLoaderCreator<SavedState> CREATOR
|
||||||
|
= new Parcelable.ClassLoaderCreator<SavedState>() {
|
||||||
|
public SavedState createFromParcel(Parcel in) {
|
||||||
|
return new SavedState(in, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SavedState createFromParcel(Parcel in, ClassLoader loader) {
|
||||||
|
return new SavedState(in, loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SavedState[] newArray(int size) {
|
||||||
|
return new SavedState[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown by {@link Fragment#instantiate(Context, String, Bundle)} when
|
* Thrown by {@link Fragment#instantiate(Context, String, Bundle)} when
|
||||||
* there is an instantiation failure.
|
* there is an instantiation failure.
|
||||||
@ -623,6 +668,22 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
|
|||||||
return mArguments;
|
return mArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the initial saved state that this Fragment should restore itself
|
||||||
|
* from when first being constructed, as returned by
|
||||||
|
* {@link FragmentManager#saveFragmentInstanceState(Fragment)
|
||||||
|
* FragmentManager.saveFragmentInstanceState}.
|
||||||
|
*
|
||||||
|
* @param state The state the fragment should be restored from.
|
||||||
|
*/
|
||||||
|
public void setInitialSavedState(SavedState state) {
|
||||||
|
if (mIndex >= 0) {
|
||||||
|
throw new IllegalStateException("Fragment already active");
|
||||||
|
}
|
||||||
|
mSavedFragmentState = state != null && state.mState != null
|
||||||
|
? state.mState : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional target for this fragment. This may be used, for example,
|
* Optional target for this fragment. This may be used, for example,
|
||||||
* if this fragment is being started by another, and when done wants to
|
* if this fragment is being started by another, and when done wants to
|
||||||
|
@ -273,6 +273,30 @@ public abstract class FragmentManager {
|
|||||||
*/
|
*/
|
||||||
public abstract Fragment getFragment(Bundle bundle, String key);
|
public abstract Fragment getFragment(Bundle bundle, String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the current instance state of the given Fragment. This can be
|
||||||
|
* used later when creating a new instance of the Fragment and adding
|
||||||
|
* it to the fragment manager, to have it create itself to match the
|
||||||
|
* current state returned here. Note that there are limits on how
|
||||||
|
* this can be used:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>The Fragment must currently be attached to the FragmentManager.
|
||||||
|
* <li>A new Fragment created using this saved state must be the same class
|
||||||
|
* type as the Fragment it was created from.
|
||||||
|
* <li>The saved state can not contain dependencies on other fragments --
|
||||||
|
* that is it can't use {@link #putFragment(Bundle, String, Fragment)} to
|
||||||
|
* store a fragment reference because that reference may not be valid when
|
||||||
|
* this saved state is later used. Likewise the Fragment's target and
|
||||||
|
* result code are not included in this state.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param f The Fragment whose state is to be saved.
|
||||||
|
* @return The generated state. This will be null if there was no
|
||||||
|
* interesting state created by the fragment.
|
||||||
|
*/
|
||||||
|
public abstract Fragment.SavedState saveFragmentInstanceState(Fragment f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print the FragmentManager's state into the given stream.
|
* Print the FragmentManager's state into the given stream.
|
||||||
*
|
*
|
||||||
@ -491,6 +515,19 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) {
|
||||||
|
if (fragment.mIndex < 0) {
|
||||||
|
throw new IllegalStateException("Fragment " + fragment
|
||||||
|
+ " is not currently in the FragmentManager");
|
||||||
|
}
|
||||||
|
if (fragment.mState > Fragment.INITIALIZING) {
|
||||||
|
Bundle result = saveFragmentBasicState(fragment);
|
||||||
|
return result != null ? new Fragment.SavedState(result) : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder(128);
|
StringBuilder sb = new StringBuilder(128);
|
||||||
@ -715,7 +752,6 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
if (f.mView != null) {
|
if (f.mView != null) {
|
||||||
f.mView.setSaveFromParentEnabled(false);
|
f.mView.setSaveFromParentEnabled(false);
|
||||||
if (f.mHidden) f.mView.setVisibility(View.GONE);
|
if (f.mHidden) f.mView.setVisibility(View.GONE);
|
||||||
f.restoreViewState();
|
|
||||||
f.onViewCreated(f.mView, f.mSavedFragmentState);
|
f.onViewCreated(f.mView, f.mSavedFragmentState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -747,7 +783,6 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
container.addView(f.mView);
|
container.addView(f.mView);
|
||||||
}
|
}
|
||||||
if (f.mHidden) f.mView.setVisibility(View.GONE);
|
if (f.mHidden) f.mView.setVisibility(View.GONE);
|
||||||
f.restoreViewState();
|
|
||||||
f.onViewCreated(f.mView, f.mSavedFragmentState);
|
f.onViewCreated(f.mView, f.mSavedFragmentState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -759,6 +794,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
+ " did not call through to super.onActivityCreated()");
|
+ " did not call through to super.onActivityCreated()");
|
||||||
}
|
}
|
||||||
if (f.mView != null) {
|
if (f.mView != null) {
|
||||||
|
f.restoreViewState();
|
||||||
}
|
}
|
||||||
f.mSavedFragmentState = null;
|
f.mSavedFragmentState = null;
|
||||||
}
|
}
|
||||||
@ -1375,6 +1411,8 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
}
|
}
|
||||||
if (mStateArray == null) {
|
if (mStateArray == null) {
|
||||||
mStateArray = new SparseArray<Parcelable>();
|
mStateArray = new SparseArray<Parcelable>();
|
||||||
|
} else {
|
||||||
|
mStateArray.clear();
|
||||||
}
|
}
|
||||||
f.mView.saveHierarchyState(mStateArray);
|
f.mView.saveHierarchyState(mStateArray);
|
||||||
if (mStateArray.size() > 0) {
|
if (mStateArray.size() > 0) {
|
||||||
@ -1383,6 +1421,32 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bundle saveFragmentBasicState(Fragment f) {
|
||||||
|
Bundle result = null;
|
||||||
|
|
||||||
|
if (mStateBundle == null) {
|
||||||
|
mStateBundle = new Bundle();
|
||||||
|
}
|
||||||
|
f.onSaveInstanceState(mStateBundle);
|
||||||
|
if (!mStateBundle.isEmpty()) {
|
||||||
|
result = mStateBundle;
|
||||||
|
mStateBundle = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f.mView != null) {
|
||||||
|
saveFragmentViewState(f);
|
||||||
|
if (f.mSavedViewState != null) {
|
||||||
|
if (result == null) {
|
||||||
|
result = new Bundle();
|
||||||
|
}
|
||||||
|
result.putSparseParcelableArray(
|
||||||
|
FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Parcelable saveAllState() {
|
Parcelable saveAllState() {
|
||||||
// Make sure all pending operations have now been executed to get
|
// Make sure all pending operations have now been executed to get
|
||||||
// our state update-to-date.
|
// our state update-to-date.
|
||||||
@ -1407,25 +1471,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
|||||||
active[i] = fs;
|
active[i] = fs;
|
||||||
|
|
||||||
if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
|
if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
|
||||||
if (mStateBundle == null) {
|
fs.mSavedFragmentState = saveFragmentBasicState(f);
|
||||||
mStateBundle = new Bundle();
|
|
||||||
}
|
|
||||||
f.onSaveInstanceState(mStateBundle);
|
|
||||||
if (!mStateBundle.isEmpty()) {
|
|
||||||
fs.mSavedFragmentState = mStateBundle;
|
|
||||||
mStateBundle = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f.mView != null) {
|
|
||||||
saveFragmentViewState(f);
|
|
||||||
if (f.mSavedViewState != null) {
|
|
||||||
if (fs.mSavedFragmentState == null) {
|
|
||||||
fs.mSavedFragmentState = new Bundle();
|
|
||||||
}
|
|
||||||
fs.mSavedFragmentState.putSparseParcelableArray(
|
|
||||||
FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f.mTarget != null) {
|
if (f.mTarget != null) {
|
||||||
if (f.mTarget.mIndex < 0) {
|
if (f.mTarget.mIndex < 0) {
|
||||||
|
@ -1980,6 +1980,9 @@ public final class Parcel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
|
||||||
|
return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
|
||||||
|
}
|
||||||
return creator.createFromParcel(this);
|
return creator.createFromParcel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,4 +113,22 @@ public interface Parcelable {
|
|||||||
*/
|
*/
|
||||||
public T[] newArray(int size);
|
public T[] newArray(int size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialization of {@link Creator} that allows you to receive the
|
||||||
|
* ClassLoader the object is being created in.
|
||||||
|
*/
|
||||||
|
public interface ClassLoaderCreator<T> extends Creator<T> {
|
||||||
|
/**
|
||||||
|
* Create a new instance of the Parcelable class, instantiating it
|
||||||
|
* from the given Parcel whose data had previously been written by
|
||||||
|
* {@link Parcelable#writeToParcel Parcelable.writeToParcel()} and
|
||||||
|
* using the given ClassLoader.
|
||||||
|
*
|
||||||
|
* @param source The Parcel to read the object's data from.
|
||||||
|
* @param loader The ClassLoader that this object is being created in.
|
||||||
|
* @return Returns a new instance of the Parcelable class.
|
||||||
|
*/
|
||||||
|
public T createFromParcel(Parcel source, ClassLoader loader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user