1515 */
1616package org .taptwo .android .widget ;
1717
18- import java .util .ArrayList ;
18+ import java .util .EnumSet ;
1919import java .util .LinkedList ;
2020
2121import org .taptwo .android .widget .viewflow .R ;
@@ -67,6 +67,8 @@ public class ViewFlow extends AdapterView<Adapter> {
6767 private int mNextScreen = INVALID_SCREEN ;
6868 private boolean mFirstLayout = true ;
6969 private ViewSwitchListener mViewSwitchListener ;
70+ private ViewLazyInitializeListener mViewInitializeListener ;
71+ private EnumSet <LazyInit > mLazyInit = EnumSet .allOf (LazyInit .class );
7072 private Adapter mAdapter ;
7173 private int mLastScrollDirection ;
7274 private AdapterDataSetObserver mDataSetObserver ;
@@ -100,6 +102,14 @@ public static interface ViewSwitchListener {
100102
101103 }
102104
105+ public static interface ViewLazyInitializeListener {
106+ void onViewLazyInitialize (View view , int position );
107+ }
108+
109+ enum LazyInit {
110+ LEFT , RIGHT
111+ }
112+
103113 public ViewFlow (Context context ) {
104114 super (context );
105115 mSideBuffer = 3 ;
@@ -218,18 +228,21 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
218228 break ;
219229
220230 case MotionEvent .ACTION_MOVE :
221- final int xDiff = (int ) Math . abs ( x - mLastMotionX );
231+ final int deltaX = (int ) ( mLastMotionX - x );
222232
223- boolean xMoved = xDiff > mTouchSlop ;
233+ boolean xMoved = Math . abs ( deltaX ) > mTouchSlop ;
224234
225235 if (xMoved ) {
226236 // Scroll if the user moved far enough along the X axis
227237 mTouchState = TOUCH_STATE_SCROLLING ;
238+
239+ if (mViewInitializeListener != null )
240+ initializeView (deltaX );
228241 }
229242
230243 if (mTouchState == TOUCH_STATE_SCROLLING ) {
231244 // Scroll to follow the motion event
232- final int deltaX = ( int ) ( mLastMotionX - x );
245+
233246 mLastMotionX = x ;
234247
235248 final int scrollX = getScrollX ();
@@ -313,18 +326,21 @@ public boolean onTouchEvent(MotionEvent ev) {
313326 break ;
314327
315328 case MotionEvent .ACTION_MOVE :
316- final int xDiff = (int ) Math . abs ( x - mLastMotionX );
329+ final int deltaX = (int ) ( mLastMotionX - x );
317330
318- boolean xMoved = xDiff > mTouchSlop ;
331+ boolean xMoved = Math . abs ( deltaX ) > mTouchSlop ;
319332
320333 if (xMoved ) {
321334 // Scroll if the user moved far enough along the X axis
322335 mTouchState = TOUCH_STATE_SCROLLING ;
336+
337+ if (mViewInitializeListener != null )
338+ initializeView (deltaX );
323339 }
324340
325341 if (mTouchState == TOUCH_STATE_SCROLLING ) {
326342 // Scroll to follow the motion event
327- final int deltaX = ( int ) ( mLastMotionX - x );
343+
328344 mLastMotionX = x ;
329345
330346 final int scrollX = getScrollX ();
@@ -377,6 +393,22 @@ && mCurrentScreen < getChildCount() - 1) {
377393 return true ;
378394 }
379395
396+ private void initializeView (final float direction ) {
397+ if (direction > 0 ) {
398+ if (mLazyInit .contains (LazyInit .RIGHT )) {
399+ mLazyInit .remove (LazyInit .RIGHT );
400+ if (mCurrentBufferIndex +1 < mLoadedViews .size ())
401+ mViewInitializeListener .onViewLazyInitialize (mLoadedViews .get (mCurrentBufferIndex + 1 ), mCurrentAdapterIndex + 1 );
402+ }
403+ } else {
404+ if (mLazyInit .contains (LazyInit .LEFT )) {
405+ mLazyInit .remove (LazyInit .LEFT );
406+ if (mCurrentBufferIndex > 0 )
407+ mViewInitializeListener .onViewLazyInitialize (mLoadedViews .get (mCurrentBufferIndex - 1 ), mCurrentAdapterIndex - 1 );
408+ }
409+ }
410+ }
411+
380412 @ Override
381413 protected void onScrollChanged (int h , int v , int oldh , int oldv ) {
382414 super .onScrollChanged (h , v , oldh , oldv );
@@ -459,6 +491,10 @@ public void setOnViewSwitchListener(ViewSwitchListener l) {
459491 mViewSwitchListener = l ;
460492 }
461493
494+ public void setOnViewLazyInitializeListener (ViewLazyInitializeListener l ) {
495+ mViewInitializeListener = l ;
496+ }
497+
462498 @ Override
463499 public Adapter getAdapter () {
464500 return mAdapter ;
@@ -538,7 +574,10 @@ public void setSelection(int position) {
538574
539575 View currentView = makeAndAddView (position , true );
540576 mLoadedViews .addLast (currentView );
541-
577+
578+ if (mViewInitializeListener != null )
579+ mViewInitializeListener .onViewLazyInitialize (currentView , position );
580+
542581 for (int offset = 1 ; mSideBuffer - offset >= 0 ; offset ++) {
543582 int leftIndex = position - offset ;
544583 int rightIndex = position + offset ;
@@ -554,27 +593,28 @@ public void setSelection(int position) {
554593 requestLayout ();
555594 setVisibleView (mCurrentBufferIndex , false );
556595 if (mIndicator != null ) {
557- mIndicator .onSwitched (mLoadedViews .get (mCurrentBufferIndex ),
558- mCurrentAdapterIndex );
596+ mIndicator .onSwitched (currentView , mCurrentAdapterIndex );
559597 }
560598 if (mViewSwitchListener != null ) {
561- mViewSwitchListener
562- .onSwitched (mLoadedViews .get (mCurrentBufferIndex ),
563- mCurrentAdapterIndex );
599+ mViewSwitchListener .onSwitched (currentView , mCurrentAdapterIndex );
564600 }
565601 }
566602
567603 private void resetFocus () {
568604 logBuffer ();
569605 recycleViews ();
570606 removeAllViewsInLayout ();
607+ mLazyInit .addAll (EnumSet .allOf (LazyInit .class ));
571608
572609 for (int i = Math .max (0 , mCurrentAdapterIndex - mSideBuffer ); i < Math
573610 .min (mAdapter .getCount (), mCurrentAdapterIndex + mSideBuffer
574611 + 1 ); i ++) {
575612 mLoadedViews .addLast (makeAndAddView (i , true ));
576- if (i == mCurrentAdapterIndex )
613+ if (i == mCurrentAdapterIndex ) {
577614 mCurrentBufferIndex = mLoadedViews .size () - 1 ;
615+ if (mViewInitializeListener != null )
616+ mViewInitializeListener .onViewLazyInitialize (mLoadedViews .getLast (), mCurrentAdapterIndex );
617+ }
578618 }
579619 logBuffer ();
580620 requestLayout ();
@@ -587,6 +627,8 @@ private void postViewSwitched(int direction) {
587627 if (direction > 0 ) { // to the right
588628 mCurrentAdapterIndex ++;
589629 mCurrentBufferIndex ++;
630+ mLazyInit .remove (LazyInit .LEFT );
631+ mLazyInit .add (LazyInit .RIGHT );
590632
591633 // Recycle view outside buffer range
592634 if (mCurrentAdapterIndex > mSideBuffer ) {
@@ -602,6 +644,8 @@ private void postViewSwitched(int direction) {
602644 } else { // to the left
603645 mCurrentAdapterIndex --;
604646 mCurrentBufferIndex --;
647+ mLazyInit .add (LazyInit .LEFT );
648+ mLazyInit .remove (LazyInit .RIGHT );
605649
606650 // Recycle view outside buffer range
607651 if (mAdapter .getCount () - 1 - mCurrentAdapterIndex > mSideBuffer ) {
0 commit comments