Merge "Lifecycle guarantees for target fragments"

This commit is contained in:
TreeHugger Robot
2017-01-27 02:45:13 +00:00
committed by Android (Google) Code Review
2 changed files with 33 additions and 0 deletions

View File

@@ -762,6 +762,24 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
* are going to call back with {@link #onActivityResult(int, int, Intent)}.
*/
public void setTargetFragment(Fragment fragment, int requestCode) {
// Don't allow a caller to set a target fragment in another FragmentManager,
// but there's a snag: people do set target fragments before fragments get added.
// We'll have the FragmentManager check that for validity when we move
// the fragments to a valid state.
final FragmentManager mine = getFragmentManager();
final FragmentManager theirs = fragment.getFragmentManager();
if (mine != null && theirs != null && mine != theirs) {
throw new IllegalArgumentException("Fragment " + fragment
+ " must share the same FragmentManager to be set as a target fragment");
}
// Don't let someone create a cycle.
for (Fragment check = fragment; check != null; check = check.getTargetFragment()) {
if (check == this) {
throw new IllegalArgumentException("Setting " + fragment + " as the target of "
+ this + " would create a target cycle");
}
}
mTarget = fragment;
mTargetRequestCode = requestCode;
}

View File

@@ -1110,10 +1110,25 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
}
}
}
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
// If we have a target fragment, push it along to at least CREATED
// so that this one can rely on it as an initialized dependency.
if (f.mTarget != null) {
if (!mActive.contains(f.mTarget)) {
throw new IllegalStateException("Fragment " + f
+ " declared target fragment " + f.mTarget
+ " that does not belong to this FragmentManager!");
}
if (f.mTarget.mState < Fragment.CREATED) {
moveToState(f.mTarget, Fragment.CREATED, 0, 0, true);
}
}
dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
f.mCalled = false;
f.onAttach(mHost.getContext());