Merge "Fix issues 5158104 and 4981556 (fragment problems)"

This commit is contained in:
Dianne Hackborn
2011-08-29 18:40:21 -07:00
committed by Android (Google) Code Review
5 changed files with 46 additions and 56 deletions

View File

@@ -3277,6 +3277,7 @@ package android.app {
method public void setArguments(android.os.Bundle); method public void setArguments(android.os.Bundle);
method public void setHasOptionsMenu(boolean); method public void setHasOptionsMenu(boolean);
method public void setInitialSavedState(android.app.Fragment.SavedState); method public void setInitialSavedState(android.app.Fragment.SavedState);
method public void setMenuVisibility(boolean);
method public void setRetainInstance(boolean); method public void setRetainInstance(boolean);
method public void setTargetFragment(android.app.Fragment, int); method public void setTargetFragment(android.app.Fragment, int);
method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent);
@@ -3342,6 +3343,7 @@ package android.app {
method public abstract java.lang.CharSequence getBreadCrumbTitle(); method public abstract java.lang.CharSequence getBreadCrumbTitle();
method public abstract int getBreadCrumbTitleRes(); method public abstract int getBreadCrumbTitleRes();
method public abstract int getId(); method public abstract int getId();
method public abstract java.lang.String getName();
} }
public static abstract interface FragmentManager.OnBackStackChangedListener { public static abstract interface FragmentManager.OnBackStackChangedListener {

View File

@@ -4206,7 +4206,6 @@ public class Activity extends ContextThemeWrapper
fragment.mContainerId = containerId; fragment.mContainerId = containerId;
fragment.mTag = tag; fragment.mTag = tag;
fragment.mInLayout = true; fragment.mInLayout = true;
fragment.mImmediateActivity = this;
fragment.mFragmentManager = mFragments; fragment.mFragmentManager = mFragments;
fragment.onInflate(this, attrs, fragment.mSavedFragmentState); fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
mFragments.addFragment(fragment, true); mFragments.addFragment(fragment, true);
@@ -4222,7 +4221,6 @@ public class Activity extends ContextThemeWrapper
// This fragment was retained from a previous instance; get it // This fragment was retained from a previous instance; get it
// going now. // going now.
fragment.mInLayout = true; fragment.mInLayout = true;
fragment.mImmediateActivity = this;
// If this fragment is newly instantiated (either right now, or // If this fragment is newly instantiated (either right now, or
// from last saved state), then give it the attributes to // from last saved state), then give it the attributes to
// initialize itself. // initialize itself.

View File

@@ -344,10 +344,6 @@ final class BackStackRecord extends FragmentTransaction implements
} }
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) { private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
if (fragment.mImmediateActivity != null) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
fragment.mImmediateActivity = mManager.mActivity;
fragment.mFragmentManager = mManager; fragment.mFragmentManager = mManager;
if (tag != null) { if (tag != null) {
@@ -388,11 +384,6 @@ final class BackStackRecord extends FragmentTransaction implements
} }
public FragmentTransaction remove(Fragment fragment) { public FragmentTransaction remove(Fragment fragment) {
if (fragment.mImmediateActivity == null) {
throw new IllegalStateException("Fragment not added: " + fragment);
}
fragment.mImmediateActivity = null;
Op op = new Op(); Op op = new Op();
op.cmd = OP_REMOVE; op.cmd = OP_REMOVE;
op.fragment = fragment; op.fragment = fragment;
@@ -402,10 +393,6 @@ final class BackStackRecord extends FragmentTransaction implements
} }
public FragmentTransaction hide(Fragment fragment) { public FragmentTransaction hide(Fragment fragment) {
if (fragment.mImmediateActivity == null) {
throw new IllegalStateException("Fragment not added: " + fragment);
}
Op op = new Op(); Op op = new Op();
op.cmd = OP_HIDE; op.cmd = OP_HIDE;
op.fragment = fragment; op.fragment = fragment;
@@ -415,10 +402,6 @@ final class BackStackRecord extends FragmentTransaction implements
} }
public FragmentTransaction show(Fragment fragment) { public FragmentTransaction show(Fragment fragment) {
if (fragment.mImmediateActivity == null) {
throw new IllegalStateException("Fragment not added: " + fragment);
}
Op op = new Op(); Op op = new Op();
op.cmd = OP_SHOW; op.cmd = OP_SHOW;
op.fragment = fragment; op.fragment = fragment;
@@ -428,10 +411,6 @@ final class BackStackRecord extends FragmentTransaction implements
} }
public FragmentTransaction detach(Fragment fragment) { public FragmentTransaction detach(Fragment fragment) {
//if (fragment.mImmediateActivity == null) {
// throw new IllegalStateException("Fragment not added: " + fragment);
//}
Op op = new Op(); Op op = new Op();
op.cmd = OP_DETACH; op.cmd = OP_DETACH;
op.fragment = fragment; op.fragment = fragment;
@@ -441,10 +420,6 @@ final class BackStackRecord extends FragmentTransaction implements
} }
public FragmentTransaction attach(Fragment fragment) { public FragmentTransaction attach(Fragment fragment) {
//if (fragment.mImmediateActivity == null) {
// throw new IllegalStateException("Fragment not added: " + fragment);
//}
Op op = new Op(); Op op = new Op();
op.cmd = OP_ATTACH; op.cmd = OP_ATTACH;
op.fragment = fragment; op.fragment = fragment;
@@ -663,7 +638,6 @@ final class BackStackRecord extends FragmentTransaction implements
case OP_ADD: { case OP_ADD: {
Fragment f = op.fragment; Fragment f = op.fragment;
f.mNextAnim = op.popExitAnim; f.mNextAnim = op.popExitAnim;
f.mImmediateActivity = null;
mManager.removeFragment(f, mManager.removeFragment(f,
FragmentManagerImpl.reverseTransit(mTransition), FragmentManagerImpl.reverseTransit(mTransition),
mTransitionStyle); mTransitionStyle);
@@ -671,7 +645,6 @@ final class BackStackRecord extends FragmentTransaction implements
case OP_REPLACE: { case OP_REPLACE: {
Fragment f = op.fragment; Fragment f = op.fragment;
f.mNextAnim = op.popExitAnim; f.mNextAnim = op.popExitAnim;
f.mImmediateActivity = null;
mManager.removeFragment(f, mManager.removeFragment(f,
FragmentManagerImpl.reverseTransit(mTransition), FragmentManagerImpl.reverseTransit(mTransition),
mTransitionStyle); mTransitionStyle);
@@ -679,7 +652,6 @@ final class BackStackRecord extends FragmentTransaction implements
for (int i=0; i<op.removed.size(); i++) { for (int i=0; i<op.removed.size(); i++) {
Fragment old = op.removed.get(i); Fragment old = op.removed.get(i);
old.mNextAnim = op.popEnterAnim; old.mNextAnim = op.popEnterAnim;
f.mImmediateActivity = mManager.mActivity;
mManager.addFragment(old, false); mManager.addFragment(old, false);
} }
} }
@@ -687,7 +659,6 @@ final class BackStackRecord extends FragmentTransaction implements
case OP_REMOVE: { case OP_REMOVE: {
Fragment f = op.fragment; Fragment f = op.fragment;
f.mNextAnim = op.popEnterAnim; f.mNextAnim = op.popEnterAnim;
f.mImmediateActivity = mManager.mActivity;
mManager.addFragment(f, false); mManager.addFragment(f, false);
} break; } break;
case OP_HIDE: { case OP_HIDE: {

View File

@@ -402,10 +402,6 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
// from all transactions. // from all transactions.
FragmentManager mFragmentManager; FragmentManager mFragmentManager;
// Set as soon as a fragment is added to a transaction (or removed),
// to be able to do validation.
Activity mImmediateActivity;
// Activity this fragment is attached to. // Activity this fragment is attached to.
Activity mActivity; Activity mActivity;
@@ -439,6 +435,9 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
// If set this fragment has menu items to contribute. // If set this fragment has menu items to contribute.
boolean mHasMenu; boolean mHasMenu;
// Set to true to allow the fragment's menu to be shown.
boolean mMenuVisible = true;
// Used to verify that subclasses call through to super class. // Used to verify that subclasses call through to super class.
boolean mCalled; boolean mCalled;
@@ -889,6 +888,24 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
} }
} }
/**
* Set a hint for whether this fragment's menu should be visible. This
* is useful if you know that a fragment has been placed in your view
* hierarchy so that the user can not currently seen it, so any menu items
* it has should also not be shown.
*
* @param menuVisible The default is true, meaning the fragment's menu will
* be shown as usual. If false, the user will not see the menu.
*/
public void setMenuVisibility(boolean menuVisible) {
if (mMenuVisible != menuVisible) {
mMenuVisible = menuVisible;
if (mHasMenu && isAdded() && !isHidden()) {
mFragmentManager.invalidateOptionsMenu();
}
}
}
/** /**
* Return the LoaderManager for this fragment, creating it if needed. * Return the LoaderManager for this fragment, creating it if needed.
*/ */
@@ -1233,7 +1250,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
mRestored = false; mRestored = false;
mBackStackNesting = 0; mBackStackNesting = 0;
mFragmentManager = null; mFragmentManager = null;
mActivity = mImmediateActivity = null; mActivity = null;
mFragmentId = 0; mFragmentId = 0;
mContainerId = 0; mContainerId = 0;
mTag = null; mTag = null;
@@ -1421,17 +1438,14 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
writer.print(" mInLayout="); writer.println(mInLayout); writer.print(" mInLayout="); writer.println(mInLayout);
writer.print(prefix); writer.print("mHidden="); writer.print(mHidden); writer.print(prefix); writer.print("mHidden="); writer.print(mHidden);
writer.print(" mDetached="); writer.print(mDetached); writer.print(" mDetached="); writer.print(mDetached);
writer.print(" mRetainInstance="); writer.print(mRetainInstance); writer.print(" mMenuVisible="); writer.print(mMenuVisible);
writer.print(" mRetaining="); writer.print(mRetaining);
writer.print(" mHasMenu="); writer.println(mHasMenu); writer.print(" mHasMenu="); writer.println(mHasMenu);
writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
writer.print(" mRetaining="); writer.println(mRetaining);
if (mFragmentManager != null) { if (mFragmentManager != null) {
writer.print(prefix); writer.print("mFragmentManager="); writer.print(prefix); writer.print("mFragmentManager=");
writer.println(mFragmentManager); writer.println(mFragmentManager);
} }
if (mImmediateActivity != null) {
writer.print(prefix); writer.print("mImmediateActivity=");
writer.println(mImmediateActivity);
}
if (mActivity != null) { if (mActivity != null) {
writer.print(prefix); writer.print("mActivity="); writer.print(prefix); writer.print("mActivity=");
writer.println(mActivity); writer.println(mActivity);

View File

@@ -66,6 +66,13 @@ public abstract class FragmentManager {
*/ */
public int getId(); public int getId();
/**
* Get the name that was supplied to
* {@link FragmentTransaction#addToBackStack(String)
* FragmentTransaction.addToBackStack(String)} when creating this entry.
*/
public String getName();
/** /**
* Return the full bread crumb title resource identifier for the entry, * Return the full bread crumb title resource identifier for the entry,
* or 0 if it does not have one. * or 0 if it does not have one.
@@ -949,7 +956,6 @@ final class FragmentManagerImpl extends FragmentManager {
if (!f.mRetaining) { if (!f.mRetaining) {
makeInactive(f); makeInactive(f);
} else { } else {
f.mImmediateActivity = null;
f.mActivity = null; f.mActivity = null;
f.mFragmentManager = null; f.mFragmentManager = null;
} }
@@ -1037,7 +1043,7 @@ final class FragmentManagerImpl extends FragmentManager {
mAdded.add(fragment); mAdded.add(fragment);
fragment.mAdded = true; fragment.mAdded = true;
fragment.mRemoving = false; fragment.mRemoving = false;
if (fragment.mHasMenu) { if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true; mNeedMenuInvalidate = true;
} }
if (moveToStateNow) { if (moveToStateNow) {
@@ -1051,7 +1057,7 @@ final class FragmentManagerImpl extends FragmentManager {
final boolean inactive = !fragment.isInBackStack(); final boolean inactive = !fragment.isInBackStack();
if (!fragment.mDetached || inactive) { if (!fragment.mDetached || inactive) {
mAdded.remove(fragment); mAdded.remove(fragment);
if (fragment.mHasMenu) { if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true; mNeedMenuInvalidate = true;
} }
fragment.mAdded = false; fragment.mAdded = false;
@@ -1086,7 +1092,7 @@ final class FragmentManagerImpl extends FragmentManager {
fragment.mView.setVisibility(View.GONE); fragment.mView.setVisibility(View.GONE);
} }
} }
if (fragment.mAdded && fragment.mHasMenu) { if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true; mNeedMenuInvalidate = true;
} }
fragment.onHiddenChanged(true); fragment.onHiddenChanged(true);
@@ -1106,7 +1112,7 @@ final class FragmentManagerImpl extends FragmentManager {
} }
fragment.mView.setVisibility(View.VISIBLE); fragment.mView.setVisibility(View.VISIBLE);
} }
if (fragment.mAdded && fragment.mHasMenu) { if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true; mNeedMenuInvalidate = true;
} }
fragment.onHiddenChanged(false); fragment.onHiddenChanged(false);
@@ -1120,7 +1126,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (fragment.mAdded) { if (fragment.mAdded) {
// We are not already in back stack, so need to remove the fragment. // We are not already in back stack, so need to remove the fragment.
mAdded.remove(fragment); mAdded.remove(fragment);
if (fragment.mHasMenu) { if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true; mNeedMenuInvalidate = true;
} }
fragment.mAdded = false; fragment.mAdded = false;
@@ -1136,7 +1142,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (!fragment.mAdded) { if (!fragment.mAdded) {
mAdded.add(fragment); mAdded.add(fragment);
fragment.mAdded = true; fragment.mAdded = true;
if (fragment.mHasMenu) { if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true; mNeedMenuInvalidate = true;
} }
moveToState(fragment, mCurState, transition, transitionStyle); moveToState(fragment, mCurState, transition, transitionStyle);
@@ -1640,7 +1646,6 @@ final class FragmentManagerImpl extends FragmentManager {
"No instantiated fragment for index #" + fms.mAdded[i]); "No instantiated fragment for index #" + fms.mAdded[i]);
} }
f.mAdded = true; f.mAdded = true;
f.mImmediateActivity = mActivity;
if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f); if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f);
mAdded.add(f); mAdded.add(f);
} }
@@ -1748,7 +1753,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (mActive != null) { if (mActive != null) {
for (int i=0; i<mAdded.size(); i++) { for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i); Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu) { if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
show = true; show = true;
f.onCreateOptionsMenu(menu, inflater); f.onCreateOptionsMenu(menu, inflater);
if (newMenus == null) { if (newMenus == null) {
@@ -1778,7 +1783,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (mActive != null) { if (mActive != null) {
for (int i=0; i<mAdded.size(); i++) { for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i); Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu) { if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
show = true; show = true;
f.onPrepareOptionsMenu(menu); f.onPrepareOptionsMenu(menu);
} }
@@ -1791,7 +1796,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (mActive != null) { if (mActive != null) {
for (int i=0; i<mAdded.size(); i++) { for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i); Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu) { if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
if (f.onOptionsItemSelected(item)) { if (f.onOptionsItemSelected(item)) {
return true; return true;
} }
@@ -1819,7 +1824,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (mActive != null) { if (mActive != null) {
for (int i=0; i<mAdded.size(); i++) { for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i); Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu) { if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
f.onOptionsMenuClosed(menu); f.onOptionsMenuClosed(menu);
} }
} }