diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-08-29 16:53:49 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2011-08-29 17:58:17 -0700 |
commit | 6c285977a0dc9605348bd9530282c7d006cbf8bd (patch) | |
tree | 51e82d31ba70c5d33b573a99e6ad09cca03e01dd /core | |
parent | b5d80fca2eb7f6053e6d404a0d4a7c213dad1317 (diff) | |
download | frameworks_base-6c285977a0dc9605348bd9530282c7d006cbf8bd.zip frameworks_base-6c285977a0dc9605348bd9530282c7d006cbf8bd.tar.gz frameworks_base-6c285977a0dc9605348bd9530282c7d006cbf8bd.tar.bz2 |
Fix issues 5158104 and 4981556 (fragment problems)
5158104: com.android.contacts: java.lang.IllegalStateException:
Can not perform this action after onSaveInstanceState at
android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1201)
The ViewPager can just commit without worrying about a state loss,
since it can correctly reconstruct its state later.
4981556: Fragment.mImmediateActivity doesn't get restored on orientation change
I am giving up on this thing; I just don't see how it can actually
be correct. So now instead of getting an exception about a dup
add/remove at point of the add/remove call, this will happen later when
processing the transaction.
Also add an API for controlling the visibility of menus, which ViewPager
can use to have the correct menus shows. And add a method to get the
name of a back stack entry.
Change-Id: Idcba14cfa2a172545a7a2a2c466cb49ceb789619
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/app/Activity.java | 2 | ||||
-rw-r--r-- | core/java/android/app/BackStackRecord.java | 29 | ||||
-rw-r--r-- | core/java/android/app/Fragment.java | 40 | ||||
-rw-r--r-- | core/java/android/app/FragmentManager.java | 29 |
4 files changed, 44 insertions, 56 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 1271ddd..0e3eaaa 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -4206,7 +4206,6 @@ public class Activity extends ContextThemeWrapper fragment.mContainerId = containerId; fragment.mTag = tag; fragment.mInLayout = true; - fragment.mImmediateActivity = this; fragment.mFragmentManager = mFragments; fragment.onInflate(this, attrs, fragment.mSavedFragmentState); mFragments.addFragment(fragment, true); @@ -4222,7 +4221,6 @@ public class Activity extends ContextThemeWrapper // This fragment was retained from a previous instance; get it // going now. fragment.mInLayout = true; - fragment.mImmediateActivity = this; // If this fragment is newly instantiated (either right now, or // from last saved state), then give it the attributes to // initialize itself. diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java index 93330a7..e9e8e16 100644 --- a/core/java/android/app/BackStackRecord.java +++ b/core/java/android/app/BackStackRecord.java @@ -344,10 +344,6 @@ final class BackStackRecord extends FragmentTransaction implements } 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; if (tag != null) { @@ -388,11 +384,6 @@ final class BackStackRecord extends FragmentTransaction implements } public FragmentTransaction remove(Fragment fragment) { - if (fragment.mImmediateActivity == null) { - throw new IllegalStateException("Fragment not added: " + fragment); - } - fragment.mImmediateActivity = null; - Op op = new Op(); op.cmd = OP_REMOVE; op.fragment = fragment; @@ -402,10 +393,6 @@ final class BackStackRecord extends FragmentTransaction implements } public FragmentTransaction hide(Fragment fragment) { - if (fragment.mImmediateActivity == null) { - throw new IllegalStateException("Fragment not added: " + fragment); - } - Op op = new Op(); op.cmd = OP_HIDE; op.fragment = fragment; @@ -415,10 +402,6 @@ final class BackStackRecord extends FragmentTransaction implements } public FragmentTransaction show(Fragment fragment) { - if (fragment.mImmediateActivity == null) { - throw new IllegalStateException("Fragment not added: " + fragment); - } - Op op = new Op(); op.cmd = OP_SHOW; op.fragment = fragment; @@ -428,10 +411,6 @@ final class BackStackRecord extends FragmentTransaction implements } public FragmentTransaction detach(Fragment fragment) { - //if (fragment.mImmediateActivity == null) { - // throw new IllegalStateException("Fragment not added: " + fragment); - //} - Op op = new Op(); op.cmd = OP_DETACH; op.fragment = fragment; @@ -441,10 +420,6 @@ final class BackStackRecord extends FragmentTransaction implements } public FragmentTransaction attach(Fragment fragment) { - //if (fragment.mImmediateActivity == null) { - // throw new IllegalStateException("Fragment not added: " + fragment); - //} - Op op = new Op(); op.cmd = OP_ATTACH; op.fragment = fragment; @@ -663,7 +638,6 @@ final class BackStackRecord extends FragmentTransaction implements case OP_ADD: { Fragment f = op.fragment; f.mNextAnim = op.popExitAnim; - f.mImmediateActivity = null; mManager.removeFragment(f, FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle); @@ -671,7 +645,6 @@ final class BackStackRecord extends FragmentTransaction implements case OP_REPLACE: { Fragment f = op.fragment; f.mNextAnim = op.popExitAnim; - f.mImmediateActivity = null; mManager.removeFragment(f, FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle); @@ -679,7 +652,6 @@ final class BackStackRecord extends FragmentTransaction implements for (int i=0; i<op.removed.size(); i++) { Fragment old = op.removed.get(i); old.mNextAnim = op.popEnterAnim; - f.mImmediateActivity = mManager.mActivity; mManager.addFragment(old, false); } } @@ -687,7 +659,6 @@ final class BackStackRecord extends FragmentTransaction implements case OP_REMOVE: { Fragment f = op.fragment; f.mNextAnim = op.popEnterAnim; - f.mImmediateActivity = mManager.mActivity; mManager.addFragment(f, false); } break; case OP_HIDE: { diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index a8621f8..3a08e6d 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -402,10 +402,6 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene // from all transactions. 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 mActivity; @@ -438,7 +434,10 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene // If set this fragment has menu items to contribute. 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. boolean mCalled; @@ -888,7 +887,25 @@ 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. */ @@ -1233,7 +1250,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene mRestored = false; mBackStackNesting = 0; mFragmentManager = null; - mActivity = mImmediateActivity = null; + mActivity = null; mFragmentId = 0; mContainerId = 0; mTag = null; @@ -1421,17 +1438,14 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene writer.print(" mInLayout="); writer.println(mInLayout); writer.print(prefix); writer.print("mHidden="); writer.print(mHidden); writer.print(" mDetached="); writer.print(mDetached); - writer.print(" mRetainInstance="); writer.print(mRetainInstance); - writer.print(" mRetaining="); writer.print(mRetaining); + writer.print(" mMenuVisible="); writer.print(mMenuVisible); writer.print(" mHasMenu="); writer.println(mHasMenu); + writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance); + writer.print(" mRetaining="); writer.println(mRetaining); if (mFragmentManager != null) { writer.print(prefix); writer.print("mFragmentManager="); writer.println(mFragmentManager); } - if (mImmediateActivity != null) { - writer.print(prefix); writer.print("mImmediateActivity="); - writer.println(mImmediateActivity); - } if (mActivity != null) { writer.print(prefix); writer.print("mActivity="); writer.println(mActivity); diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 70e6866..7a6759f 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -67,6 +67,13 @@ public abstract class FragmentManager { 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, * or 0 if it does not have one. */ @@ -949,7 +956,6 @@ final class FragmentManagerImpl extends FragmentManager { if (!f.mRetaining) { makeInactive(f); } else { - f.mImmediateActivity = null; f.mActivity = null; f.mFragmentManager = null; } @@ -1037,7 +1043,7 @@ final class FragmentManagerImpl extends FragmentManager { mAdded.add(fragment); fragment.mAdded = true; fragment.mRemoving = false; - if (fragment.mHasMenu) { + if (fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; } if (moveToStateNow) { @@ -1051,7 +1057,7 @@ final class FragmentManagerImpl extends FragmentManager { final boolean inactive = !fragment.isInBackStack(); if (!fragment.mDetached || inactive) { mAdded.remove(fragment); - if (fragment.mHasMenu) { + if (fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; } fragment.mAdded = false; @@ -1086,7 +1092,7 @@ final class FragmentManagerImpl extends FragmentManager { fragment.mView.setVisibility(View.GONE); } } - if (fragment.mAdded && fragment.mHasMenu) { + if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; } fragment.onHiddenChanged(true); @@ -1106,7 +1112,7 @@ final class FragmentManagerImpl extends FragmentManager { } fragment.mView.setVisibility(View.VISIBLE); } - if (fragment.mAdded && fragment.mHasMenu) { + if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; } fragment.onHiddenChanged(false); @@ -1120,7 +1126,7 @@ final class FragmentManagerImpl extends FragmentManager { if (fragment.mAdded) { // We are not already in back stack, so need to remove the fragment. mAdded.remove(fragment); - if (fragment.mHasMenu) { + if (fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; } fragment.mAdded = false; @@ -1136,7 +1142,7 @@ final class FragmentManagerImpl extends FragmentManager { if (!fragment.mAdded) { mAdded.add(fragment); fragment.mAdded = true; - if (fragment.mHasMenu) { + if (fragment.mHasMenu && fragment.mMenuVisible) { mNeedMenuInvalidate = true; } moveToState(fragment, mCurState, transition, transitionStyle); @@ -1640,7 +1646,6 @@ final class FragmentManagerImpl extends FragmentManager { "No instantiated fragment for index #" + fms.mAdded[i]); } f.mAdded = true; - f.mImmediateActivity = mActivity; if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f); mAdded.add(f); } @@ -1748,7 +1753,7 @@ final class FragmentManagerImpl extends FragmentManager { if (mActive != null) { for (int i=0; i<mAdded.size(); i++) { Fragment f = mAdded.get(i); - if (f != null && !f.mHidden && f.mHasMenu) { + if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) { show = true; f.onCreateOptionsMenu(menu, inflater); if (newMenus == null) { @@ -1778,7 +1783,7 @@ final class FragmentManagerImpl extends FragmentManager { if (mActive != null) { for (int i=0; i<mAdded.size(); i++) { Fragment f = mAdded.get(i); - if (f != null && !f.mHidden && f.mHasMenu) { + if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) { show = true; f.onPrepareOptionsMenu(menu); } @@ -1791,7 +1796,7 @@ final class FragmentManagerImpl extends FragmentManager { if (mActive != null) { for (int i=0; i<mAdded.size(); 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)) { return true; } @@ -1819,7 +1824,7 @@ final class FragmentManagerImpl extends FragmentManager { if (mActive != null) { for (int i=0; i<mAdded.size(); 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); } } |