Skip to content

Commit d1a040c

Browse files
committed
Fix bug 6499508
Using a HashSet for the recycled views, instead of an ArrayList, to ensure items are not double-added
1 parent 72d6835 commit d1a040c

File tree

2 files changed

+17
-49
lines changed

2 files changed

+17
-49
lines changed

packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
import com.android.systemui.SwipeHelper;
4242
import com.android.systemui.recent.RecentsPanelView.TaskDescriptionAdapter;
4343

44-
import java.util.ArrayList;
44+
import java.util.HashSet;
45+
import java.util.Iterator;
4546

4647
public class RecentsHorizontalScrollView extends HorizontalScrollView
4748
implements SwipeHelper.Callback, RecentsPanelView.RecentsScrollView {
@@ -53,7 +54,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
5354
protected int mLastScrollPosition;
5455
private SwipeHelper mSwipeHelper;
5556
private RecentsScrollViewPerformanceHelper mPerformanceHelper;
56-
private ArrayList<View> mRecycledViews;
57+
private HashSet<View> mRecycledViews;
5758
private int mNumItemsInOneScreenful;
5859

5960
public RecentsHorizontalScrollView(Context context, AttributeSet attrs) {
@@ -62,7 +63,7 @@ public RecentsHorizontalScrollView(Context context, AttributeSet attrs) {
6263
float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
6364
mSwipeHelper = new SwipeHelper(SwipeHelper.Y, this, densityScale, pagingTouchSlop);
6465
mPerformanceHelper = RecentsScrollViewPerformanceHelper.create(context, attrs, this, false);
65-
mRecycledViews = new ArrayList<View>();
66+
mRecycledViews = new HashSet<View>();
6667
}
6768

6869
public void setMinSwipeAlpha(float minAlpha) {
@@ -89,16 +90,12 @@ private void update() {
8990
setLayoutTransition(null);
9091

9192
mLinearLayout.removeAllViews();
92-
for (int i = 0; i < mRecycledViews.size(); i++) {
93-
View child = mRecycledViews.get(i);
94-
if (child.getParent() != null) {
95-
throw new RuntimeException("Recycled child has a parent");
96-
}
97-
}
93+
Iterator<View> recycledViews = mRecycledViews.iterator();
9894
for (int i = 0; i < mAdapter.getCount(); i++) {
9995
View old = null;
100-
if (mRecycledViews.size() != 0) {
101-
old = mRecycledViews.remove(mRecycledViews.size() - 1);
96+
if (recycledViews.hasNext()) {
97+
old = recycledViews.next();
98+
recycledViews.remove();
10299
old.setVisibility(VISIBLE);
103100
}
104101

@@ -195,9 +192,6 @@ public void dismissChild(View v) {
195192
public void onChildDismissed(View v) {
196193
addToRecycledViews(v);
197194
mLinearLayout.removeView(v);
198-
if (v.getParent() != null) {
199-
throw new RuntimeException("Recycled child has parent");
200-
}
201195
mCallback.handleSwipe(v);
202196
// Restore the alpha/translation parameters to what they were before swiping
203197
// (for when these items are recycled)
@@ -369,15 +363,9 @@ public void onInvalidated() {
369363
mNumItemsInOneScreenful =
370364
(int) FloatMath.ceil(dm.widthPixels / (float) child.getMeasuredWidth());
371365
addToRecycledViews(child);
372-
if (child.getParent() != null) {
373-
throw new RuntimeException("First recycled child has parent");
374-
}
375366

376367
for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) {
377368
addToRecycledViews(mAdapter.createView(mLinearLayout));
378-
if (mRecycledViews.get(mRecycledViews.size() - 1).getParent() != null) {
379-
throw new RuntimeException("Recycled child has parent");
380-
}
381369
}
382370
}
383371

packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
import com.android.systemui.SwipeHelper;
4242
import com.android.systemui.recent.RecentsPanelView.TaskDescriptionAdapter;
4343

44-
import java.util.ArrayList;
44+
import java.util.HashSet;
45+
import java.util.Iterator;
4546

4647
public class RecentsVerticalScrollView extends ScrollView
4748
implements SwipeHelper.Callback, RecentsPanelView.RecentsScrollView {
@@ -53,7 +54,7 @@ public class RecentsVerticalScrollView extends ScrollView
5354
protected int mLastScrollPosition;
5455
private SwipeHelper mSwipeHelper;
5556
private RecentsScrollViewPerformanceHelper mPerformanceHelper;
56-
private ArrayList<View> mRecycledViews;
57+
private HashSet<View> mRecycledViews;
5758
private int mNumItemsInOneScreenful;
5859

5960
public RecentsVerticalScrollView(Context context, AttributeSet attrs) {
@@ -63,7 +64,7 @@ public RecentsVerticalScrollView(Context context, AttributeSet attrs) {
6364
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
6465

6566
mPerformanceHelper = RecentsScrollViewPerformanceHelper.create(context, attrs, this, true);
66-
mRecycledViews = new ArrayList<View>();
67+
mRecycledViews = new HashSet<View>();
6768
}
6869

6970
public void setMinSwipeAlpha(float minAlpha) {
@@ -90,26 +91,20 @@ private void update() {
9091
setLayoutTransition(null);
9192

9293
mLinearLayout.removeAllViews();
93-
for (int i = 0; i < mRecycledViews.size(); i++) {
94-
View child = mRecycledViews.get(i);
95-
if (child.getParent() != null) {
96-
throw new RuntimeException("Recycled child has parent");
97-
}
98-
}
94+
9995
// Once we can clear the data associated with individual item views,
10096
// we can get rid of the removeAllViews() and the code below will
10197
// recycle them.
98+
Iterator<View> recycledViews = mRecycledViews.iterator();
10299
for (int i = 0; i < mAdapter.getCount(); i++) {
103100
View old = null;
104-
if (mRecycledViews.size() != 0) {
105-
old = mRecycledViews.remove(mRecycledViews.size() - 1);
101+
if (recycledViews.hasNext()) {
102+
old = recycledViews.next();
103+
recycledViews.remove();
106104
old.setVisibility(VISIBLE);
107105
}
108106

109107
final View view = mAdapter.getView(i, old, mLinearLayout);
110-
if (view.getParent() != null) {
111-
throw new RuntimeException("Recycled child has parent");
112-
}
113108

114109
if (mPerformanceHelper != null) {
115110
mPerformanceHelper.addViewCallback(view);
@@ -148,9 +143,6 @@ public boolean onLongClick(View v) {
148143
thumbnailView.setClickable(true);
149144
thumbnailView.setOnClickListener(launchAppListener);
150145
thumbnailView.setOnLongClickListener(longClickListener);
151-
if (view.getParent() != null) {
152-
throw new RuntimeException("Recycled child has parent");
153-
}
154146

155147
// We don't want to dismiss recents if a user clicks on the app title
156148
// (we also don't want to launch the app either, though, because the
@@ -160,9 +152,6 @@ public boolean onLongClick(View v) {
160152
appTitle.setOnTouchListener(noOpListener);
161153
final View calloutLine = view.findViewById(R.id.recents_callout_line);
162154
calloutLine.setOnTouchListener(noOpListener);
163-
if (view.getParent() != null) {
164-
throw new RuntimeException("Recycled child has parent");
165-
}
166155

167156
mLinearLayout.addView(view);
168157
}
@@ -211,9 +200,6 @@ public void dismissChild(View v) {
211200
public void onChildDismissed(View v) {
212201
addToRecycledViews(v);
213202
mLinearLayout.removeView(v);
214-
if (v.getParent() != null) {
215-
throw new RuntimeException("Recycled child has parent");
216-
}
217203
mCallback.handleSwipe(v);
218204
// Restore the alpha/translation parameters to what they were before swiping
219205
// (for when these items are recycled)
@@ -387,15 +373,9 @@ public void onInvalidated() {
387373
mNumItemsInOneScreenful =
388374
(int) FloatMath.ceil(dm.heightPixels / (float) child.getMeasuredHeight());
389375
addToRecycledViews(child);
390-
if (child.getParent() != null) {
391-
throw new RuntimeException("First recycled child has parent");
392-
}
393376

394377
for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) {
395378
addToRecycledViews(mAdapter.createView(mLinearLayout));
396-
if (mRecycledViews.get(mRecycledViews.size() - 1).getParent() != null) {
397-
throw new RuntimeException("Recycled child has parent");
398-
}
399379
}
400380
}
401381

0 commit comments

Comments
 (0)