Merge "Primary navigation fragments"
This commit is contained in:
committed by
Android (Google) Code Review
commit
53ff0bdfb9
@@ -4687,6 +4687,7 @@ package android.app {
|
||||
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
|
||||
method public abstract int getBackStackEntryCount();
|
||||
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
|
||||
method public abstract android.app.Fragment getPrimaryNavigationFragment();
|
||||
method public void invalidateOptionsMenu();
|
||||
method public abstract boolean isDestroyed();
|
||||
method public abstract void popBackStack();
|
||||
@@ -4763,6 +4764,7 @@ package android.app {
|
||||
method public abstract android.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
|
||||
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
|
||||
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
|
||||
method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
|
||||
method public abstract android.app.FragmentTransaction setTransition(int);
|
||||
method public abstract android.app.FragmentTransaction setTransitionStyle(int);
|
||||
method public abstract android.app.FragmentTransaction show(android.app.Fragment);
|
||||
|
||||
@@ -4847,6 +4847,7 @@ package android.app {
|
||||
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
|
||||
method public abstract int getBackStackEntryCount();
|
||||
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
|
||||
method public abstract android.app.Fragment getPrimaryNavigationFragment();
|
||||
method public void invalidateOptionsMenu();
|
||||
method public abstract boolean isDestroyed();
|
||||
method public abstract void popBackStack();
|
||||
@@ -4923,6 +4924,7 @@ package android.app {
|
||||
method public abstract android.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
|
||||
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
|
||||
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
|
||||
method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
|
||||
method public abstract android.app.FragmentTransaction setTransition(int);
|
||||
method public abstract android.app.FragmentTransaction setTransitionStyle(int);
|
||||
method public abstract android.app.FragmentTransaction show(android.app.Fragment);
|
||||
|
||||
@@ -4697,6 +4697,7 @@ package android.app {
|
||||
method public abstract android.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
|
||||
method public abstract int getBackStackEntryCount();
|
||||
method public abstract android.app.Fragment getFragment(android.os.Bundle, java.lang.String);
|
||||
method public abstract android.app.Fragment getPrimaryNavigationFragment();
|
||||
method public void invalidateOptionsMenu();
|
||||
method public abstract boolean isDestroyed();
|
||||
method public abstract void popBackStack();
|
||||
@@ -4773,6 +4774,7 @@ package android.app {
|
||||
method public abstract android.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
|
||||
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int);
|
||||
method public abstract android.app.FragmentTransaction setCustomAnimations(int, int, int, int);
|
||||
method public abstract android.app.FragmentTransaction setPrimaryNavigationFragment(android.app.Fragment);
|
||||
method public abstract android.app.FragmentTransaction setTransition(int);
|
||||
method public abstract android.app.FragmentTransaction setTransitionStyle(int);
|
||||
method public abstract android.app.FragmentTransaction show(android.app.Fragment);
|
||||
|
||||
@@ -186,6 +186,8 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
static final int OP_SHOW = 5;
|
||||
static final int OP_DETACH = 6;
|
||||
static final int OP_ATTACH = 7;
|
||||
static final int OP_SET_PRIMARY_NAV = 8;
|
||||
static final int OP_UNSET_PRIMARY_NAV = 9;
|
||||
|
||||
static final class Op {
|
||||
int cmd;
|
||||
@@ -194,6 +196,14 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
int exitAnim;
|
||||
int popEnterAnim;
|
||||
int popExitAnim;
|
||||
|
||||
Op() {
|
||||
}
|
||||
|
||||
Op(int cmd, Fragment fragment) {
|
||||
this.cmd = cmd;
|
||||
this.fragment = fragment;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Op> mOps = new ArrayList<>();
|
||||
@@ -318,6 +328,13 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
case OP_ATTACH:
|
||||
cmdStr = "ATTACH";
|
||||
break;
|
||||
case OP_SET_PRIMARY_NAV:
|
||||
cmdStr="SET_PRIMARY_NAV";
|
||||
break;
|
||||
case OP_UNSET_PRIMARY_NAV:
|
||||
cmdStr="UNSET_PRIMARY_NAV";
|
||||
break;
|
||||
|
||||
default:
|
||||
cmdStr = "cmd=" + op.cmd;
|
||||
break;
|
||||
@@ -438,10 +455,7 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
fragment.mContainerId = fragment.mFragmentId = containerViewId;
|
||||
}
|
||||
|
||||
Op op = new Op();
|
||||
op.cmd = opcmd;
|
||||
op.fragment = fragment;
|
||||
addOp(op);
|
||||
addOp(new Op(opcmd, fragment));
|
||||
}
|
||||
|
||||
public FragmentTransaction replace(int containerViewId, Fragment fragment) {
|
||||
@@ -458,46 +472,37 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
}
|
||||
|
||||
public FragmentTransaction remove(Fragment fragment) {
|
||||
Op op = new Op();
|
||||
op.cmd = OP_REMOVE;
|
||||
op.fragment = fragment;
|
||||
addOp(op);
|
||||
addOp(new Op(OP_REMOVE, fragment));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentTransaction hide(Fragment fragment) {
|
||||
Op op = new Op();
|
||||
op.cmd = OP_HIDE;
|
||||
op.fragment = fragment;
|
||||
addOp(op);
|
||||
addOp(new Op(OP_HIDE, fragment));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentTransaction show(Fragment fragment) {
|
||||
Op op = new Op();
|
||||
op.cmd = OP_SHOW;
|
||||
op.fragment = fragment;
|
||||
addOp(op);
|
||||
addOp(new Op(OP_SHOW, fragment));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentTransaction detach(Fragment fragment) {
|
||||
Op op = new Op();
|
||||
op.cmd = OP_DETACH;
|
||||
op.fragment = fragment;
|
||||
addOp(op);
|
||||
addOp(new Op(OP_DETACH, fragment));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentTransaction attach(Fragment fragment) {
|
||||
Op op = new Op();
|
||||
op.cmd = OP_ATTACH;
|
||||
op.fragment = fragment;
|
||||
addOp(op);
|
||||
addOp(new Op(OP_ATTACH, fragment));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentTransaction setPrimaryNavigationFragment(Fragment fragment) {
|
||||
addOp(new Op(OP_SET_PRIMARY_NAV, fragment));
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -689,7 +694,8 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
final int numOps = mOps.size();
|
||||
for (int opNum = 0; opNum < numOps; opNum++) {
|
||||
final Op op = mOps.get(opNum);
|
||||
if (op.fragment.mContainerId == containerId) {
|
||||
final int fragContainer = op.fragment != null ? op.fragment.mContainerId : 0;
|
||||
if (fragContainer != 0 && fragContainer == containerId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -704,7 +710,7 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
int lastContainer = -1;
|
||||
for (int opNum = 0; opNum < numOps; opNum++) {
|
||||
final Op op = mOps.get(opNum);
|
||||
final int container = op.fragment.mContainerId;
|
||||
final int container = op.fragment != null ? op.fragment.mContainerId : 0;
|
||||
if (container != 0 && container != lastContainer) {
|
||||
lastContainer = container;
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
@@ -712,7 +718,9 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
final int numThoseOps = record.mOps.size();
|
||||
for (int thoseOpIndex = 0; thoseOpIndex < numThoseOps; thoseOpIndex++) {
|
||||
final Op thatOp = record.mOps.get(thoseOpIndex);
|
||||
if (thatOp.fragment.mContainerId == container) {
|
||||
final int thatContainer = thatOp.fragment != null
|
||||
? thatOp.fragment.mContainerId : 0;
|
||||
if (thatContainer == container) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -731,7 +739,9 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
for (int opNum = 0; opNum < numOps; opNum++) {
|
||||
final Op op = mOps.get(opNum);
|
||||
final Fragment f = op.fragment;
|
||||
f.setNextTransition(mTransition, mTransitionStyle);
|
||||
if (f != null) {
|
||||
f.setNextTransition(mTransition, mTransitionStyle);
|
||||
}
|
||||
switch (op.cmd) {
|
||||
case OP_ADD:
|
||||
f.setNextAnim(op.enterAnim);
|
||||
@@ -757,10 +767,16 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
f.setNextAnim(op.enterAnim);
|
||||
mManager.attachFragment(f);
|
||||
break;
|
||||
case OP_SET_PRIMARY_NAV:
|
||||
mManager.setPrimaryNavigationFragment(f);
|
||||
break;
|
||||
case OP_UNSET_PRIMARY_NAV:
|
||||
mManager.setPrimaryNavigationFragment(null);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
|
||||
}
|
||||
if (!mAllowOptimization && op.cmd != OP_ADD) {
|
||||
if (!mAllowOptimization && op.cmd != OP_ADD && f != null) {
|
||||
mManager.moveFragmentToExpectedState(f);
|
||||
}
|
||||
}
|
||||
@@ -778,7 +794,10 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
|
||||
final Op op = mOps.get(opNum);
|
||||
Fragment f = op.fragment;
|
||||
f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
|
||||
if (f != null) {
|
||||
f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
|
||||
mTransitionStyle);
|
||||
}
|
||||
switch (op.cmd) {
|
||||
case OP_ADD:
|
||||
f.setNextAnim(op.popExitAnim);
|
||||
@@ -804,10 +823,16 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
f.setNextAnim(op.popExitAnim);
|
||||
mManager.detachFragment(f);
|
||||
break;
|
||||
case OP_SET_PRIMARY_NAV:
|
||||
mManager.setPrimaryNavigationFragment(null);
|
||||
break;
|
||||
case OP_UNSET_PRIMARY_NAV:
|
||||
mManager.setPrimaryNavigationFragment(f);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
|
||||
}
|
||||
if (!mAllowOptimization && op.cmd != OP_REMOVE) {
|
||||
if (!mAllowOptimization && op.cmd != OP_REMOVE && f != null) {
|
||||
mManager.moveFragmentToExpectedState(f);
|
||||
}
|
||||
}
|
||||
@@ -817,15 +842,28 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all OP_REPLACE ops and replaces them with the proper add and remove
|
||||
* operations that are equivalent to the replace. This must be called prior to
|
||||
* {@link #executeOps()} or any other call that operations on mOps.
|
||||
* Expands all meta-ops into their more primitive equivalents. This must be called prior to
|
||||
* {@link #executeOps()} or any other call that operations on mOps for forward navigation.
|
||||
* It should not be called for pop/reverse navigation operations.
|
||||
*
|
||||
* <p>Removes all OP_REPLACE ops and replaces them with the proper add and remove
|
||||
* operations that are equivalent to the replace.</p>
|
||||
*
|
||||
* <p>Adds OP_UNSET_PRIMARY_NAV ops to match OP_SET_PRIMARY_NAV, OP_REMOVE and OP_DETACH
|
||||
* ops so that we can restore the old primary nav fragment later. Since callers call this
|
||||
* method in a loop before running ops from several transactions at once, the caller should
|
||||
* pass the return value from this method as the oldPrimaryNav parameter for the next call.
|
||||
* The first call in such a loop should pass the value of
|
||||
* {@link FragmentManager#getPrimaryNavigationFragment()}.</p>
|
||||
*
|
||||
* @param added Initialized to the fragments that are in the mManager.mAdded, this
|
||||
* will be modified to contain the fragments that will be in mAdded
|
||||
* after the execution ({@link #executeOps()}.
|
||||
* @param oldPrimaryNav The tracked primary navigation fragment as of the beginning of
|
||||
* this set of ops
|
||||
* @return the new oldPrimaryNav fragment after this record's ops would be run
|
||||
*/
|
||||
void expandReplaceOps(ArrayList<Fragment> added) {
|
||||
Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
|
||||
for (int opNum = 0; opNum < mOps.size(); opNum++) {
|
||||
final Op op = mOps.get(opNum);
|
||||
switch (op.cmd) {
|
||||
@@ -834,22 +872,33 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
added.add(op.fragment);
|
||||
break;
|
||||
case OP_REMOVE:
|
||||
case OP_DETACH:
|
||||
case OP_DETACH: {
|
||||
added.remove(op.fragment);
|
||||
break;
|
||||
if (op.fragment == oldPrimaryNav) {
|
||||
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.fragment));
|
||||
opNum++;
|
||||
oldPrimaryNav = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OP_REPLACE: {
|
||||
Fragment f = op.fragment;
|
||||
int containerId = f.mContainerId;
|
||||
final Fragment f = op.fragment;
|
||||
final int containerId = f.mContainerId;
|
||||
boolean alreadyAdded = false;
|
||||
for (int i = added.size() - 1; i >= 0; i--) {
|
||||
Fragment old = added.get(i);
|
||||
final Fragment old = added.get(i);
|
||||
if (old.mContainerId == containerId) {
|
||||
if (old == f) {
|
||||
alreadyAdded = true;
|
||||
} else {
|
||||
Op removeOp = new Op();
|
||||
removeOp.cmd = OP_REMOVE;
|
||||
removeOp.fragment = old;
|
||||
// This is duplicated from above since we only make
|
||||
// a single pass for expanding ops. Unset any outgoing primary nav.
|
||||
if (old == oldPrimaryNav) {
|
||||
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, old));
|
||||
opNum++;
|
||||
oldPrimaryNav = null;
|
||||
}
|
||||
final Op removeOp = new Op(OP_REMOVE, old);
|
||||
removeOp.enterAnim = op.enterAnim;
|
||||
removeOp.popEnterAnim = op.popEnterAnim;
|
||||
removeOp.exitAnim = op.exitAnim;
|
||||
@@ -869,8 +918,18 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OP_SET_PRIMARY_NAV: {
|
||||
// It's ok if this is null, that means we will restore to no active
|
||||
// primary navigation fragment on a pop.
|
||||
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, oldPrimaryNav));
|
||||
opNum++;
|
||||
// Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
|
||||
oldPrimaryNav = op.fragment;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return oldPrimaryNav;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -917,8 +976,8 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
|
||||
private static boolean isFragmentPostponed(Op op) {
|
||||
final Fragment fragment = op.fragment;
|
||||
return (fragment.mAdded && fragment.mView != null && !fragment.mDetached &&
|
||||
!fragment.mHidden && fragment.isPostponed());
|
||||
return fragment != null && fragment.mAdded && fragment.mView != null && !fragment.mDetached
|
||||
&& !fragment.mHidden && fragment.isPostponed();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
||||
@@ -359,6 +359,18 @@ public abstract class FragmentManager {
|
||||
*/
|
||||
public abstract void unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb);
|
||||
|
||||
/**
|
||||
* Return the currently active primary navigation fragment for this FragmentManager.
|
||||
*
|
||||
* <p>The primary navigation fragment's
|
||||
* {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first
|
||||
* to process delegated navigation actions such as {@link #popBackStack()} if no ID
|
||||
* or transaction name is provided to pop to.</p>
|
||||
*
|
||||
* @return the fragment designated as the primary navigation fragment
|
||||
*/
|
||||
public abstract Fragment getPrimaryNavigationFragment();
|
||||
|
||||
/**
|
||||
* Print the FragmentManager's state into the given stream.
|
||||
*
|
||||
@@ -524,6 +536,7 @@ final class FragmentManagerState implements Parcelable {
|
||||
FragmentState[] mActive;
|
||||
int[] mAdded;
|
||||
BackStackState[] mBackStack;
|
||||
int mPrimaryNavActiveIndex = -1;
|
||||
|
||||
public FragmentManagerState() {
|
||||
}
|
||||
@@ -532,6 +545,7 @@ final class FragmentManagerState implements Parcelable {
|
||||
mActive = in.createTypedArray(FragmentState.CREATOR);
|
||||
mAdded = in.createIntArray();
|
||||
mBackStack = in.createTypedArray(BackStackState.CREATOR);
|
||||
mPrimaryNavActiveIndex = in.readInt();
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
@@ -542,6 +556,7 @@ final class FragmentManagerState implements Parcelable {
|
||||
dest.writeTypedArray(mActive, flags);
|
||||
dest.writeIntArray(mAdded);
|
||||
dest.writeTypedArray(mBackStack, flags);
|
||||
dest.writeInt(mPrimaryNavActiveIndex);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<FragmentManagerState> CREATOR
|
||||
@@ -626,6 +641,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
FragmentHostCallback<?> mHost;
|
||||
FragmentContainer mContainer;
|
||||
Fragment mParent;
|
||||
Fragment mPrimaryNav;
|
||||
|
||||
boolean mNeedMenuInvalidate;
|
||||
boolean mStateSaved;
|
||||
@@ -783,6 +799,16 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
execPendingActions();
|
||||
ensureExecReady(true);
|
||||
|
||||
if (mPrimaryNav != null // We have a primary nav fragment
|
||||
&& id < 0 // No valid id (since they're local)
|
||||
&& name == null) { // no name to pop to (since they're local)
|
||||
final FragmentManager childManager = mPrimaryNav.mChildFragmentManager;
|
||||
if (childManager != null && childManager.popBackStackImmediate()) {
|
||||
// We did something, just not to this specific FragmentManager. Return true.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags);
|
||||
if (executePop) {
|
||||
mExecutingActions = true;
|
||||
@@ -2038,11 +2064,12 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
if (mAdded != null) {
|
||||
mTmpAddedFragments.addAll(mAdded);
|
||||
}
|
||||
Fragment oldPrimaryNav = getPrimaryNavigationFragment();
|
||||
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
|
||||
final BackStackRecord record = records.get(recordNum);
|
||||
final boolean isPop = isRecordPop.get(recordNum);
|
||||
if (!isPop) {
|
||||
record.expandReplaceOps(mTmpAddedFragments);
|
||||
oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
|
||||
} else {
|
||||
record.trackAddedFragmentsInPop(mTmpAddedFragments);
|
||||
}
|
||||
@@ -2318,20 +2345,20 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
*/
|
||||
private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
|
||||
ArrayList<Boolean> isPop) {
|
||||
int numActions;
|
||||
boolean didSomething = false;
|
||||
synchronized (this) {
|
||||
if (mPendingActions == null || mPendingActions.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
numActions = mPendingActions.size();
|
||||
final int numActions = mPendingActions.size();
|
||||
for (int i = 0; i < numActions; i++) {
|
||||
mPendingActions.get(i).generateOps(records, isPop);
|
||||
didSomething |= mPendingActions.get(i).generateOps(records, isPop);
|
||||
}
|
||||
mPendingActions.clear();
|
||||
mHost.getHandler().removeCallbacks(mExecCommit);
|
||||
}
|
||||
return numActions > 0;
|
||||
return didSomething;
|
||||
}
|
||||
|
||||
void doPendingDeferredStart() {
|
||||
@@ -2618,6 +2645,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
fms.mActive = active;
|
||||
fms.mAdded = added;
|
||||
fms.mBackStack = backStack;
|
||||
if (mPrimaryNav != null) {
|
||||
fms.mPrimaryNavActiveIndex = mPrimaryNav.mIndex;
|
||||
}
|
||||
return fms;
|
||||
}
|
||||
|
||||
@@ -2744,6 +2774,10 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
} else {
|
||||
mBackStack = null;
|
||||
}
|
||||
|
||||
if (fms.mPrimaryNavActiveIndex >= 0) {
|
||||
mPrimaryNav = mActive.get(fms.mPrimaryNavActiveIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void attachController(FragmentHostCallback<?> host, FragmentContainer container,
|
||||
@@ -2942,6 +2976,19 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrimaryNavigationFragment(Fragment f) {
|
||||
if (f != null && (f.getFragmentManager() != this || f.mIndex >= mActive.size()
|
||||
|| mActive.get(f.mIndex) != f)) {
|
||||
throw new IllegalArgumentException("Fragment " + f
|
||||
+ " is not an active fragment of FragmentManager " + this);
|
||||
}
|
||||
mPrimaryNav = f;
|
||||
}
|
||||
|
||||
public Fragment getPrimaryNavigationFragment() {
|
||||
return mPrimaryNav;
|
||||
}
|
||||
|
||||
public void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb,
|
||||
boolean recursive) {
|
||||
if (mLifecycleCallbacks == null) {
|
||||
@@ -3386,6 +3433,16 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
|
||||
@Override
|
||||
public boolean generateOps(ArrayList<BackStackRecord> records,
|
||||
ArrayList<Boolean> isRecordPop) {
|
||||
if (mPrimaryNav != null // We have a primary nav fragment
|
||||
&& mId < 0 // No valid id (since they're local)
|
||||
&& mName == null) { // no name to pop to (since they're local)
|
||||
final FragmentManager childManager = mPrimaryNav.mChildFragmentManager;
|
||||
if (childManager != null && childManager.popBackStackImmediate()) {
|
||||
// We didn't add any operations for this FragmentManager even though
|
||||
// a child did do work.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return popBackStackState(records, isRecordPop, mName, mId, mFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,6 +131,24 @@ public abstract class FragmentTransaction {
|
||||
*/
|
||||
public abstract FragmentTransaction attach(Fragment fragment);
|
||||
|
||||
/**
|
||||
* Set a currently active fragment in this FragmentManager as the primary navigation fragment.
|
||||
*
|
||||
* <p>The primary navigation fragment's
|
||||
* {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first
|
||||
* to process delegated navigation actions such as {@link FragmentManager#popBackStack()}
|
||||
* if no ID or transaction name is provided to pop to. Navigation operations outside of the
|
||||
* fragment system may choose to delegate those actions to the primary navigation fragment
|
||||
* as returned by {@link FragmentManager#getPrimaryNavigationFragment()}.</p>
|
||||
*
|
||||
* <p>The fragment provided must currently be added to the FragmentManager to be set as
|
||||
* a primary navigation fragment, or previously added as part of this transaction.</p>
|
||||
*
|
||||
* @param fragment the fragment to set as the primary navigation fragment
|
||||
* @return the same FragmentTransaction instance
|
||||
*/
|
||||
public abstract FragmentTransaction setPrimaryNavigationFragment(Fragment fragment);
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this transaction contains no operations,
|
||||
* <code>false</code> otherwise.
|
||||
|
||||
@@ -43,14 +43,16 @@ class FragmentTransition {
|
||||
* REPLACE operations have already been replaced by add/remove operations.
|
||||
*/
|
||||
private static final int[] INVERSE_OPS = {
|
||||
BackStackRecord.OP_NULL, // inverse of OP_NULL (error)
|
||||
BackStackRecord.OP_REMOVE, // inverse of OP_ADD
|
||||
BackStackRecord.OP_NULL, // inverse of OP_REPLACE (error)
|
||||
BackStackRecord.OP_ADD, // inverse of OP_REMOVE
|
||||
BackStackRecord.OP_SHOW, // inverse of OP_HIDE
|
||||
BackStackRecord.OP_HIDE, // inverse of OP_SHOW
|
||||
BackStackRecord.OP_ATTACH, // inverse of OP_DETACH
|
||||
BackStackRecord.OP_DETACH, // inverse of OP_ATTACH
|
||||
BackStackRecord.OP_NULL, // inverse of OP_NULL (error)
|
||||
BackStackRecord.OP_REMOVE, // inverse of OP_ADD
|
||||
BackStackRecord.OP_NULL, // inverse of OP_REPLACE (error)
|
||||
BackStackRecord.OP_ADD, // inverse of OP_REMOVE
|
||||
BackStackRecord.OP_SHOW, // inverse of OP_HIDE
|
||||
BackStackRecord.OP_HIDE, // inverse of OP_SHOW
|
||||
BackStackRecord.OP_ATTACH, // inverse of OP_DETACH
|
||||
BackStackRecord.OP_DETACH, // inverse of OP_ATTACH
|
||||
BackStackRecord.OP_UNSET_PRIMARY_NAV, // inverse of OP_SET_PRIMARY_NAV
|
||||
BackStackRecord.OP_SET_PRIMARY_NAV, // inverse of OP_UNSET_PRIMARY_NAV
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1232,6 +1234,9 @@ class FragmentTransition {
|
||||
SparseArray<FragmentContainerTransition> transitioningFragments, boolean isPop,
|
||||
boolean isOptimizedTransaction) {
|
||||
final Fragment fragment = op.fragment;
|
||||
if (fragment == null) {
|
||||
return; // no fragment, no transition
|
||||
}
|
||||
final int containerId = fragment.mContainerId;
|
||||
if (containerId == 0) {
|
||||
return; // no container, no transition
|
||||
|
||||
Reference in New Issue
Block a user