@@ -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