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>
|
||||
</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"
|
||||
return="void"
|
||||
abstract="false"
|
||||
@ -30718,6 +30731,53 @@
|
||||
</parameter>
|
||||
</constructor>
|
||||
</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"
|
||||
extends="android.view.ViewGroup"
|
||||
abstract="false"
|
||||
@ -31151,6 +31211,19 @@
|
||||
<parameter name="listener" type="android.app.FragmentManager.OnBackStackChangedListener">
|
||||
</parameter>
|
||||
</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"
|
||||
type="int"
|
||||
transient="false"
|
||||
@ -150858,6 +150931,31 @@
|
||||
>
|
||||
</field>
|
||||
</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"
|
||||
abstract="true"
|
||||
static="true"
|
||||
|
@ -1875,7 +1875,7 @@ public final class ActivityThread {
|
||||
}
|
||||
deliverNewIntents(r, intents);
|
||||
if (resumed) {
|
||||
mInstrumentation.callActivityOnResume(r.activity);
|
||||
r.activity.performResume();
|
||||
r.activity.mTemporaryPause = false;
|
||||
}
|
||||
}
|
||||
@ -2831,7 +2831,7 @@ public final class ActivityThread {
|
||||
}
|
||||
deliverResults(r, res.results);
|
||||
if (resumed) {
|
||||
mInstrumentation.callActivityOnResume(r.activity);
|
||||
r.activity.performResume();
|
||||
r.activity.mTemporaryPause = false;
|
||||
}
|
||||
}
|
||||
|
@ -449,6 +449,51 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
|
||||
boolean mLoadersStarted;
|
||||
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
|
||||
* there is an instantiation failure.
|
||||
@ -623,6 +668,22 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
|
||||
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,
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@ -491,6 +515,19 @@ final class FragmentManagerImpl extends FragmentManager {
|
||||
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
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
@ -715,7 +752,6 @@ final class FragmentManagerImpl extends FragmentManager {
|
||||
if (f.mView != null) {
|
||||
f.mView.setSaveFromParentEnabled(false);
|
||||
if (f.mHidden) f.mView.setVisibility(View.GONE);
|
||||
f.restoreViewState();
|
||||
f.onViewCreated(f.mView, f.mSavedFragmentState);
|
||||
}
|
||||
}
|
||||
@ -747,7 +783,6 @@ final class FragmentManagerImpl extends FragmentManager {
|
||||
container.addView(f.mView);
|
||||
}
|
||||
if (f.mHidden) f.mView.setVisibility(View.GONE);
|
||||
f.restoreViewState();
|
||||
f.onViewCreated(f.mView, f.mSavedFragmentState);
|
||||
}
|
||||
}
|
||||
@ -759,6 +794,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
||||
+ " did not call through to super.onActivityCreated()");
|
||||
}
|
||||
if (f.mView != null) {
|
||||
f.restoreViewState();
|
||||
}
|
||||
f.mSavedFragmentState = null;
|
||||
}
|
||||
@ -1375,6 +1411,8 @@ final class FragmentManagerImpl extends FragmentManager {
|
||||
}
|
||||
if (mStateArray == null) {
|
||||
mStateArray = new SparseArray<Parcelable>();
|
||||
} else {
|
||||
mStateArray.clear();
|
||||
}
|
||||
f.mView.saveHierarchyState(mStateArray);
|
||||
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() {
|
||||
// Make sure all pending operations have now been executed to get
|
||||
// our state update-to-date.
|
||||
@ -1407,25 +1471,7 @@ final class FragmentManagerImpl extends FragmentManager {
|
||||
active[i] = fs;
|
||||
|
||||
if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
|
||||
if (mStateBundle == null) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
fs.mSavedFragmentState = saveFragmentBasicState(f);
|
||||
|
||||
if (f.mTarget != null) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -113,4 +113,22 @@ public interface Parcelable {
|
||||
*/
|
||||
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