Skip to content

Commit c20fc8d

Browse files
author
Luca Zanolin
committed
Clone the list of listeners before notifing any event.
This is required, otherwise the listener cannot remove it-self from the list of listeners during the notification. Bug: 6692355 Change-Id: I07762feb4f9b97ec4b6148d2f604d53e266b84d7
1 parent 5bb835a commit c20fc8d

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

core/java/android/animation/LayoutTransition.java

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -942,8 +942,10 @@ public void onLayoutChange(View v, int left, int top, int right, int bottom,
942942

943943
@Override
944944
public void onAnimationStart(Animator animator) {
945-
if (mListeners != null) {
946-
for (TransitionListener listener : mListeners) {
945+
if (hasListeners()) {
946+
ArrayList<TransitionListener> listeners =
947+
(ArrayList<TransitionListener>) mListeners.clone();
948+
for (TransitionListener listener : listeners) {
947949
listener.startTransition(LayoutTransition.this, parent, child,
948950
changeReason == APPEARING ?
949951
CHANGE_APPEARING : changeReason == DISAPPEARING ?
@@ -961,8 +963,10 @@ public void onAnimationCancel(Animator animator) {
961963
@Override
962964
public void onAnimationEnd(Animator animator) {
963965
currentChangingAnimations.remove(child);
964-
if (mListeners != null) {
965-
for (TransitionListener listener : mListeners) {
966+
if (hasListeners()) {
967+
ArrayList<TransitionListener> listeners =
968+
(ArrayList<TransitionListener>) mListeners.clone();
969+
for (TransitionListener listener : listeners) {
966970
listener.endTransition(LayoutTransition.this, parent, child,
967971
changeReason == APPEARING ?
968972
CHANGE_APPEARING : changeReason == DISAPPEARING ?
@@ -1131,8 +1135,10 @@ private void runAppearingTransition(final ViewGroup parent, final View child) {
11311135
currentAnimation.cancel();
11321136
}
11331137
if (mAppearingAnim == null) {
1134-
if (mListeners != null) {
1135-
for (TransitionListener listener : mListeners) {
1138+
if (hasListeners()) {
1139+
ArrayList<TransitionListener> listeners =
1140+
(ArrayList<TransitionListener>) mListeners.clone();
1141+
for (TransitionListener listener : listeners) {
11361142
listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
11371143
}
11381144
}
@@ -1149,8 +1155,10 @@ private void runAppearingTransition(final ViewGroup parent, final View child) {
11491155
@Override
11501156
public void onAnimationEnd(Animator anim) {
11511157
currentAppearingAnimations.remove(child);
1152-
if (mListeners != null) {
1153-
for (TransitionListener listener : mListeners) {
1158+
if (hasListeners()) {
1159+
ArrayList<TransitionListener> listeners =
1160+
(ArrayList<TransitionListener>) mListeners.clone();
1161+
for (TransitionListener listener : listeners) {
11541162
listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
11551163
}
11561164
}
@@ -1172,8 +1180,10 @@ private void runDisappearingTransition(final ViewGroup parent, final View child)
11721180
currentAnimation.cancel();
11731181
}
11741182
if (mDisappearingAnim == null) {
1175-
if (mListeners != null) {
1176-
for (TransitionListener listener : mListeners) {
1183+
if (hasListeners()) {
1184+
ArrayList<TransitionListener> listeners =
1185+
(ArrayList<TransitionListener>) mListeners.clone();
1186+
for (TransitionListener listener : listeners) {
11771187
listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
11781188
}
11791189
}
@@ -1189,8 +1199,10 @@ private void runDisappearingTransition(final ViewGroup parent, final View child)
11891199
public void onAnimationEnd(Animator anim) {
11901200
currentDisappearingAnimations.remove(child);
11911201
child.setAlpha(preAnimAlpha);
1192-
if (mListeners != null) {
1193-
for (TransitionListener listener : mListeners) {
1202+
if (hasListeners()) {
1203+
ArrayList<TransitionListener> listeners =
1204+
(ArrayList<TransitionListener>) mListeners.clone();
1205+
for (TransitionListener listener : listeners) {
11941206
listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
11951207
}
11961208
}
@@ -1228,8 +1240,10 @@ private void addChild(ViewGroup parent, View child, boolean changesLayout) {
12281240
cancel(CHANGE_APPEARING);
12291241
cancel(CHANGING);
12301242
}
1231-
if (mListeners != null && (mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
1232-
for (TransitionListener listener : mListeners) {
1243+
if (hasListeners() && (mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
1244+
ArrayList<TransitionListener> listeners =
1245+
(ArrayList<TransitionListener>) mListeners.clone();
1246+
for (TransitionListener listener : listeners) {
12331247
listener.startTransition(this, parent, child, APPEARING);
12341248
}
12351249
}
@@ -1241,6 +1255,10 @@ private void addChild(ViewGroup parent, View child, boolean changesLayout) {
12411255
}
12421256
}
12431257

1258+
private boolean hasListeners() {
1259+
return mListeners != null && mListeners.size() > 0;
1260+
}
1261+
12441262
/**
12451263
* This method is called by ViewGroup when there is a call to layout() on the container
12461264
* with this LayoutTransition. If the CHANGING transition is enabled and if there is no other
@@ -1328,8 +1346,10 @@ private void removeChild(ViewGroup parent, View child, boolean changesLayout) {
13281346
cancel(CHANGE_DISAPPEARING);
13291347
cancel(CHANGING);
13301348
}
1331-
if (mListeners != null && (mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
1332-
for (TransitionListener listener : mListeners) {
1349+
if (hasListeners() && (mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
1350+
ArrayList<TransitionListener> listeners = (ArrayList<TransitionListener>) mListeners
1351+
.clone();
1352+
for (TransitionListener listener : listeners) {
13331353
listener.startTransition(this, parent, child, DISAPPEARING);
13341354
}
13351355
}

0 commit comments

Comments
 (0)