Skip to content

Commit 1fccf43

Browse files
committed
Merge pull request pakerfeldt#63 from chripo/chripo/recycleviews
recycling views harder
2 parents 598035e + fdf6d24 commit 1fccf43

File tree

1 file changed

+37
-33
lines changed

1 file changed

+37
-33
lines changed

viewflow/src/org/taptwo/android/widget/ViewFlow.java

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public class ViewFlow extends AdapterView<Adapter> {
5353
private final static int TOUCH_STATE_SCROLLING = 1;
5454

5555
private LinkedList<View> mLoadedViews;
56+
private LinkedList<View> mRecycledViews;
5657
private int mCurrentBufferIndex;
5758
private int mCurrentAdapterIndex;
5859
private int mSideBuffer = 2;
@@ -121,6 +122,7 @@ public ViewFlow(Context context, AttributeSet attrs) {
121122

122123
private void init() {
123124
mLoadedViews = new LinkedList<View>();
125+
mRecycledViews = new LinkedList<View>();
124126
mScroller = new Scroller(getContext());
125127
final ViewConfiguration configuration = ViewConfiguration
126128
.get(getContext());
@@ -506,6 +508,22 @@ public void setFlowIndicator(FlowIndicator flowIndicator) {
506508
mIndicator.setViewFlow(this);
507509
}
508510

511+
protected void recycleViews() {
512+
while (!mLoadedViews.isEmpty())
513+
recycleView(mLoadedViews.remove());
514+
}
515+
516+
protected void recycleView(View v) {
517+
if (v == null)
518+
return;
519+
mRecycledViews.add(v);
520+
detachViewFromParent(v);
521+
}
522+
523+
protected View getRecycledView() {
524+
return (mRecycledViews.isEmpty() ? null : mRecycledViews.remove(0));
525+
}
526+
509527
@Override
510528
public void setSelection(int position) {
511529
mNextScreen = INVALID_SCREEN;
@@ -514,36 +532,25 @@ public void setSelection(int position) {
514532
return;
515533

516534
position = Math.max(position, 0);
517-
position = Math.min(position, mAdapter.getCount()-1);
535+
position = Math.min(position, mAdapter.getCount()-1);
518536

519-
ArrayList<View> recycleViews = new ArrayList<View>();
520-
View recycleView;
521-
while (!mLoadedViews.isEmpty()) {
522-
recycleViews.add(recycleView = mLoadedViews.remove());
523-
detachViewFromParent(recycleView);
524-
}
537+
recycleViews();
525538

526-
View currentView = makeAndAddView(position, true,
527-
(recycleViews.isEmpty() ? null : recycleViews.remove(0)));
539+
View currentView = makeAndAddView(position, true);
528540
mLoadedViews.addLast(currentView);
529541

530542
for(int offset = 1; mSideBuffer - offset >= 0; offset++) {
531543
int leftIndex = position - offset;
532544
int rightIndex = position + offset;
533545
if(leftIndex >= 0)
534-
mLoadedViews.addFirst(makeAndAddView(leftIndex, false,
535-
(recycleViews.isEmpty() ? null : recycleViews.remove(0))));
546+
mLoadedViews.addFirst(makeAndAddView(leftIndex, false));
536547
if(rightIndex < mAdapter.getCount())
537-
mLoadedViews.addLast(makeAndAddView(rightIndex, true,
538-
(recycleViews.isEmpty() ? null : recycleViews.remove(0))));
548+
mLoadedViews.addLast(makeAndAddView(rightIndex, true));
539549
}
540550

541551
mCurrentBufferIndex = mLoadedViews.indexOf(currentView);
542552
mCurrentAdapterIndex = position;
543553

544-
for (View view : recycleViews) {
545-
removeDetachedView(view, false);
546-
}
547554
requestLayout();
548555
setVisibleView(mCurrentBufferIndex, false);
549556
if (mIndicator != null) {
@@ -559,13 +566,13 @@ public void setSelection(int position) {
559566

560567
private void resetFocus() {
561568
logBuffer();
562-
mLoadedViews.clear();
569+
recycleViews();
563570
removeAllViewsInLayout();
564571

565572
for (int i = Math.max(0, mCurrentAdapterIndex - mSideBuffer); i < Math
566573
.min(mAdapter.getCount(), mCurrentAdapterIndex + mSideBuffer
567574
+ 1); i++) {
568-
mLoadedViews.addLast(makeAndAddView(i, true, null));
575+
mLoadedViews.addLast(makeAndAddView(i, true));
569576
if (i == mCurrentAdapterIndex)
570577
mCurrentBufferIndex = mLoadedViews.size() - 1;
571578
}
@@ -581,38 +588,30 @@ private void postViewSwitched(int direction) {
581588
mCurrentAdapterIndex++;
582589
mCurrentBufferIndex++;
583590

584-
View recycleView = null;
585-
586-
// Remove view outside buffer range
591+
// Recycle view outside buffer range
587592
if (mCurrentAdapterIndex > mSideBuffer) {
588-
recycleView = mLoadedViews.removeFirst();
589-
detachViewFromParent(recycleView);
590-
// removeView(recycleView);
593+
recycleView(mLoadedViews.removeFirst());
591594
mCurrentBufferIndex--;
592595
}
593596

594597
// Add new view to buffer
595598
int newBufferIndex = mCurrentAdapterIndex + mSideBuffer;
596599
if (newBufferIndex < mAdapter.getCount())
597-
mLoadedViews.addLast(makeAndAddView(newBufferIndex, true,
598-
recycleView));
600+
mLoadedViews.addLast(makeAndAddView(newBufferIndex, true));
599601

600602
} else { // to the left
601603
mCurrentAdapterIndex--;
602604
mCurrentBufferIndex--;
603-
View recycleView = null;
604605

605-
// Remove view outside buffer range
606+
// Recycle view outside buffer range
606607
if (mAdapter.getCount() - 1 - mCurrentAdapterIndex > mSideBuffer) {
607-
recycleView = mLoadedViews.removeLast();
608-
detachViewFromParent(recycleView);
608+
recycleView(mLoadedViews.removeLast());
609609
}
610610

611611
// Add new view to buffer
612612
int newBufferIndex = mCurrentAdapterIndex - mSideBuffer;
613613
if (newBufferIndex > -1) {
614-
mLoadedViews.addFirst(makeAndAddView(newBufferIndex, false,
615-
recycleView));
614+
mLoadedViews.addFirst(makeAndAddView(newBufferIndex, false));
616615
mCurrentBufferIndex++;
617616
}
618617

@@ -647,6 +646,10 @@ private View setupChild(View child, boolean addToEnd, boolean recycle) {
647646
return child;
648647
}
649648

649+
private View makeAndAddView(int position, boolean addToEnd) {
650+
return makeAndAddView(position, addToEnd, getRecycledView());
651+
}
652+
650653
private View makeAndAddView(int position, boolean addToEnd, View convertView) {
651654
View view = mAdapter.getView(position, convertView, this);
652655
return setupChild(view, addToEnd, convertView != null);
@@ -678,7 +681,8 @@ public void onInvalidated() {
678681
private void logBuffer() {
679682

680683
Log.d("viewflow", "Size of mLoadedViews: " + mLoadedViews.size() +
681-
"X: " + mScroller.getCurrX() + ", Y: " + mScroller.getCurrY());
684+
", Size of mRecycledViews: " + mRecycledViews.size() +
685+
", X: " + mScroller.getCurrX() + ", Y: " + mScroller.getCurrY());
682686
Log.d("viewflow", "IndexInAdapter: " + mCurrentAdapterIndex
683687
+ ", IndexInBuffer: " + mCurrentBufferIndex);
684688
}

0 commit comments

Comments
 (0)