summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author George Mount <mount@google.com> 2015-11-30 10:32:47 -0800
committer George Mount <mount@google.com> 2015-11-30 10:58:37 -0800
commitfbaa14bc35e8d7366596053cac8a445084bac44c (patch)
tree04f8201325fd97f54f4439354d11c2a517190c75
parent2b2d23aa706c2d8efb05e15f08bdc41883a4a651 (diff)
Choose the correct Fragment to pull a Transiton from.
Bug 25375640 When popping multiple back stacks or replacing multiple times within a transaction, the wrong fragment could have been chosen. This normally occured when one of the Fragments had a null Transition. Change-Id: Ic2c842d9228ee7d26bf067016cb3f307bdf92991
-rw-r--r--core/java/android/app/BackStackRecord.java61
1 files changed, 37 insertions, 24 deletions
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 754a5710191b..b24bce3107d1 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -798,21 +798,33 @@ final class BackStackRecord extends FragmentTransaction implements
}
}
- private static void setFirstOut(SparseArray<Fragment> fragments, Fragment fragment) {
+ private static void setFirstOut(SparseArray<Fragment> firstOutFragments,
+ SparseArray<Fragment> lastInFragments, Fragment fragment) {
if (fragment != null) {
int containerId = fragment.mContainerId;
- if (containerId != 0 && !fragment.isHidden() && fragment.isAdded() &&
- fragment.getView() != null && fragments.get(containerId) == null) {
- fragments.put(containerId, fragment);
+ if (containerId != 0 && !fragment.isHidden()) {
+ if (fragment.isAdded() && fragment.getView() != null
+ && firstOutFragments.get(containerId) == null) {
+ firstOutFragments.put(containerId, fragment);
+ }
+ if (lastInFragments.get(containerId) == fragment) {
+ lastInFragments.remove(containerId);
+ }
}
}
}
- private void setLastIn(SparseArray<Fragment> fragments, Fragment fragment) {
+ private void setLastIn(SparseArray<Fragment> firstOutFragments,
+ SparseArray<Fragment> lastInFragments, Fragment fragment) {
if (fragment != null) {
int containerId = fragment.mContainerId;
if (containerId != 0) {
- fragments.put(containerId, fragment);
+ if (!fragment.isAdded()) {
+ lastInFragments.put(containerId, fragment);
+ }
+ if (firstOutFragments.get(containerId) == fragment) {
+ firstOutFragments.remove(containerId);
+ }
}
}
}
@@ -835,7 +847,7 @@ final class BackStackRecord extends FragmentTransaction implements
while (op != null) {
switch (op.cmd) {
case OP_ADD:
- setLastIn(lastInFragments, op.fragment);
+ setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_REPLACE: {
Fragment f = op.fragment;
@@ -845,29 +857,30 @@ final class BackStackRecord extends FragmentTransaction implements
if (f == null || old.mContainerId == f.mContainerId) {
if (old == f) {
f = null;
+ lastInFragments.remove(old.mContainerId);
} else {
- setFirstOut(firstOutFragments, old);
+ setFirstOut(firstOutFragments, lastInFragments, old);
}
}
}
}
- setLastIn(lastInFragments, f);
+ setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
}
case OP_REMOVE:
- setFirstOut(firstOutFragments, op.fragment);
+ setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_HIDE:
- setFirstOut(firstOutFragments, op.fragment);
+ setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_SHOW:
- setLastIn(lastInFragments, op.fragment);
+ setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_DETACH:
- setFirstOut(firstOutFragments, op.fragment);
+ setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_ATTACH:
- setLastIn(lastInFragments, op.fragment);
+ setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
}
@@ -889,38 +902,38 @@ final class BackStackRecord extends FragmentTransaction implements
if (!mManager.mContainer.onHasView()) {
return; // nothing to see, so no transitions
}
- Op op = mHead;
+ Op op = mTail;
while (op != null) {
switch (op.cmd) {
case OP_ADD:
- setFirstOut(firstOutFragments, op.fragment);
+ setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_REPLACE:
if (op.removed != null) {
for (int i = op.removed.size() - 1; i >= 0; i--) {
- setLastIn(lastInFragments, op.removed.get(i));
+ setLastIn(firstOutFragments, lastInFragments, op.removed.get(i));
}
}
- setFirstOut(firstOutFragments, op.fragment);
+ setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_REMOVE:
- setLastIn(lastInFragments, op.fragment);
+ setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_HIDE:
- setLastIn(lastInFragments, op.fragment);
+ setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_SHOW:
- setFirstOut(firstOutFragments, op.fragment);
+ setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_DETACH:
- setLastIn(lastInFragments, op.fragment);
+ setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
case OP_ATTACH:
- setFirstOut(firstOutFragments, op.fragment);
+ setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
}
- op = op.next;
+ op = op.prev;
}
}