10
10
import org .freeflow .utils .ViewUtils ;
11
11
12
12
import android .content .Context ;
13
+ import android .graphics .Canvas ;
13
14
import android .graphics .Rect ;
14
15
import android .support .v4 .util .SimpleArrayMap ;
15
16
import android .util .AttributeSet ;
25
26
import android .view .View ;
26
27
import android .view .ViewConfiguration ;
27
28
import android .widget .Checkable ;
28
- import android .widget .Scroller ;
29
+ import android .widget .EdgeEffect ;
30
+ import android .widget .OverScroller ;
29
31
30
32
public class Container extends AbsLayoutContainer {
31
33
@@ -64,9 +66,11 @@ public class Container extends AbsLayoutContainer {
64
66
private Runnable mPendingCheckForTap ;
65
67
private Runnable mPendingCheckForLongPress ;
66
68
67
- private Scroller scroller ;
69
+ private OverScroller scroller ;
68
70
private boolean flingStarted = false ;
69
71
72
+ private EdgeEffect mLeftEdge , mRightEdge , mTopEdge , mBottomEdge ;
73
+
70
74
// This flag controls whether onTap/onLongPress/onTouch trigger
71
75
// the ActionMode
72
76
// private boolean mDataChanged = false;
@@ -127,13 +131,20 @@ protected void init(Context context) {
127
131
// usedViews = new HashMap<Object, ItemProxy>();
128
132
// usedHeaderViews = new HashMap<Object, ItemProxy>();
129
133
134
+ setWillNotDraw (false );
135
+
130
136
viewpool = new ViewPool ();
131
137
frames = new HashMap <Object , ItemProxy >();
132
138
133
139
maxFlingVelocity = ViewConfiguration .get (context ).getScaledMaximumFlingVelocity ();
134
140
touchSlop = ViewConfiguration .get (context ).getScaledTouchSlop ();
135
- scroller = new Scroller (context );
136
- // scroller.setFriction(ViewConfiguration.getScrollFriction());
141
+
142
+ // TODO: create Scroller vars
143
+ scroller = new OverScroller (context );
144
+ mLeftEdge = new EdgeEffect (context );
145
+ mRightEdge = new EdgeEffect (context );
146
+ mTopEdge = new EdgeEffect (context );
147
+ mBottomEdge = new EdgeEffect (context );
137
148
138
149
}
139
150
@@ -151,6 +162,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
151
162
if (beforeWidth != afterWidth || beforeHeight != afterHeight || markLayoutDirty ) {
152
163
computeLayout (afterWidth , afterHeight );
153
164
}
165
+
154
166
}
155
167
156
168
public void computeLayout (int w , int h ) {
@@ -226,7 +238,9 @@ private void prepareViewForAddition(View view, ItemProxy proxy) {
226
238
protected void onLayout (boolean changed , int l , int t , int r , int b ) {
227
239
// Log.d(TAG, "== onLayout ==");
228
240
// mDataChanged = false;
241
+
229
242
dispatchLayoutComplete ();
243
+
230
244
}
231
245
232
246
private void doLayout (ItemProxy proxy ) {
@@ -561,8 +575,8 @@ public boolean onTouchEvent(MotionEvent event) {
561
575
562
576
if (event .getAction () == MotionEvent .ACTION_DOWN ) {
563
577
564
- scroller .abortAnimation ( );
565
-
578
+ scroller .forceFinished ( true );
579
+
566
580
beginTouchAt = ViewUtils .getItemAt (frames , (int ) (viewPortX + event .getX ()),
567
581
(int ) (viewPortY + event .getY ()));
568
582
@@ -603,7 +617,17 @@ public boolean onTouchEvent(MotionEvent event) {
603
617
}
604
618
605
619
if (mTouchMode == TOUCH_MODE_SCROLL ) {
606
- moveScreen (event .getX () - deltaX , event .getY () - deltaY );
620
+ moveScreen (event .getX () - deltaX , event .getY () - deltaY , false );
621
+
622
+ float max = layout .getContentWidth () - getWidth () - 200 ;
623
+ Log .d (TAG , "viewport = " + viewPortX + " max = " + max );
624
+ if (viewPortX > max ) {
625
+ float val = ((float ) viewPortX - max ) / 200F ;
626
+ Log .d (TAG , "val= " + val );
627
+
628
+ // mTopEdge.onPull(val);
629
+ }
630
+
607
631
deltaX = event .getX ();
608
632
deltaY = event .getY ();
609
633
}
@@ -624,6 +648,9 @@ public boolean onTouchEvent(MotionEvent event) {
624
648
return true ;
625
649
626
650
} else if (event .getAction () == MotionEvent .ACTION_UP ) {
651
+
652
+ // mTopEdge.onRelease();
653
+
627
654
if (mTouchMode == TOUCH_MODE_SCROLL ) {
628
655
mVelocityTracker .computeCurrentVelocity (1000 , maxFlingVelocity );
629
656
@@ -637,36 +664,16 @@ public boolean onTouchEvent(MotionEvent event) {
637
664
if (Math .abs (mVelocityTracker .getXVelocity ()) > 100 || Math .abs (mVelocityTracker .getYVelocity ()) > 100 ) {
638
665
639
666
// TODO: add scroller call here...
640
- // scroller.forceFinished(true);
641
- // scroller.abortAnimation();
667
+ // scroller.forceFinished(true);
668
+ // scroller.abortAnimation();
642
669
643
670
flingStarted = true ;
644
671
scroller .fling (viewPortX , viewPortY , -(int ) mVelocityTracker .getXVelocity (),
645
672
-(int ) mVelocityTracker .getYVelocity (), 0 , layout .getContentWidth () - getWidth (), 0 ,
646
- layout .getContentHeight () - getHeight ());
673
+ layout .getContentHeight () - getHeight (), 300 , 300 );
647
674
648
675
post (scrollRunnable );
649
676
650
- // final float velocityX = mVelocityTracker.getXVelocity();
651
- // final float velocityY = mVelocityTracker.getYVelocity();
652
- // ValueAnimator animator = ValueAnimator.ofFloat(1, 0);
653
- // animator.addUpdateListener(new AnimatorUpdateListener() {
654
- //
655
- // @Override
656
- // public void onAnimationUpdate(ValueAnimator animation) {
657
- // int translateX = (int) ((1 -
658
- // animation.getAnimatedFraction()) * velocityX / 350);
659
- // int translateY = (int) ((1 -
660
- // animation.getAnimatedFraction()) * velocityY / 350);
661
- //
662
- // moveScreen(translateX, translateY);
663
- //
664
- // }
665
- // });
666
- //
667
- // animator.setDuration(500);
668
- // animator.start();
669
-
670
677
}
671
678
mTouchMode = TOUCH_MODE_REST ;
672
679
Log .d (TAG , "Setting to rest" );
@@ -718,7 +725,7 @@ public ItemProxy getSelectedItemProxy() {
718
725
return selectedItemProxy ;
719
726
}
720
727
721
- //TODO: scroll runnable
728
+ // TODO: scroll runnable
722
729
private Runnable scrollRunnable = new Runnable () {
723
730
724
731
@ Override
@@ -730,14 +737,37 @@ public void run() {
730
737
731
738
boolean more = scroller .computeScrollOffset ();
732
739
740
+ if ((flingStarted || mLeftEdge .isFinished ()) && viewPortX < 0 && layout .horizontalDragEnabled ()) {
741
+ mLeftEdge .finish ();
742
+ mLeftEdge .onAbsorb ((int ) scroller .getCurrVelocity ());
743
+ }
744
+
745
+ if ((flingStarted || mRightEdge .isFinished ()) && viewPortX > layout .getContentWidth () - getMeasuredWidth ()
746
+ && layout .horizontalDragEnabled ()) {
747
+ mRightEdge .finish ();
748
+ mRightEdge .onAbsorb ((int ) scroller .getCurrVelocity ());
749
+ }
750
+
751
+ if ((flingStarted || mTopEdge .isFinished ()) && viewPortY < 0 && layout .verticalDragEnabled ()) {
752
+ mTopEdge .finish ();
753
+ mTopEdge .onAbsorb ((int ) scroller .getCurrVelocity ());
754
+ }
755
+
756
+ if ((flingStarted || mBottomEdge .isFinished ())
757
+ && viewPortY > layout .getContentHeight () - getMeasuredHeight () && layout .verticalDragEnabled ()) {
758
+ mBottomEdge .finish ();
759
+ mBottomEdge .onAbsorb ((int ) scroller .getCurrVelocity ());
760
+ }
761
+
733
762
if (flingStarted ) {
734
763
flingStarted = false ;
735
764
scrollDeltaX = scroller .getCurrX ();
736
765
scrollDeltaY = scroller .getCurrY ();
737
766
}
738
767
739
- Log .d ("scrolling" , "vel = " + scroller .getCurrVelocity () + ", cur x = " + scroller .getCurrX ()
740
- + ", cur y = " + scroller .getCurrY () + ", vp x = " + viewPortX );
768
+ // Log.d("scrolling", "vel = " + scroller.getCurrVelocity() +
769
+ // ", cur x = " + scroller.getCurrX()
770
+ // + ", cur y = " + scroller.getCurrY() + ", vp x = " + viewPortX);
741
771
int x = scroller .getCurrX ();
742
772
int y = scroller .getCurrY ();
743
773
@@ -747,15 +777,15 @@ public void run() {
747
777
scrollDeltaX = x ;
748
778
scrollDeltaY = y ;
749
779
750
- moveScreen (-diffx , -diffy );
780
+ moveScreen (-diffx , -diffy , true );
751
781
752
782
if (more ) {
753
783
post (scrollRunnable );
754
784
}
755
785
}
756
786
};
757
787
758
- private void moveScreen (float movementX , float movementY ) {
788
+ private void moveScreen (float movementX , float movementY , boolean fling ) {
759
789
760
790
if (layout .horizontalDragEnabled ()) {
761
791
viewPortX = (int ) (viewPortX - movementX );
@@ -772,16 +802,17 @@ private void moveScreen(float movementX, float movementY) {
772
802
scrollableWidth = layout .getContentWidth () - getWidth ();
773
803
scrollableHeight = layout .getContentHeight () - getHeight ();
774
804
775
- if (viewPortX < 0 )
776
- viewPortX = 0 ;
777
- else if (viewPortX > scrollableWidth )
778
- viewPortX = scrollableWidth ;
779
-
780
- if (viewPortY < 0 )
781
- viewPortY = 0 ;
782
- else if (viewPortY > scrollableHeight )
783
- viewPortY = scrollableHeight ;
805
+ if (!fling ) {
806
+ if (viewPortX < 0 )
807
+ viewPortX = 0 ;
808
+ else if (viewPortX > scrollableWidth )
809
+ viewPortX = scrollableWidth ;
784
810
811
+ if (viewPortY < 0 )
812
+ viewPortY = 0 ;
813
+ else if (viewPortY > scrollableHeight )
814
+ viewPortY = scrollableHeight ;
815
+ }
785
816
HashMap <? extends Object , ItemProxy > oldFrames = frames ;
786
817
787
818
frames = new HashMap <Object , ItemProxy >(layout .getItemProxies (viewPortX , viewPortY ));
@@ -805,6 +836,66 @@ else if (viewPortY > scrollableHeight)
805
836
806
837
}
807
838
839
+ @ Override
840
+ protected void onDraw (Canvas canvas ) {
841
+ super .onDraw (canvas );
842
+
843
+ boolean needsInvalidate = false ;
844
+
845
+ final int height = getMeasuredHeight () - getPaddingTop () - getPaddingBottom ();
846
+ final int width = getMeasuredWidth ();
847
+
848
+ if (!mLeftEdge .isFinished ()) {
849
+ // Log.d("EdgeView", "edge not finished");
850
+ final int restoreCount = canvas .save ();
851
+
852
+ canvas .rotate (270 );
853
+ canvas .translate (-height + getPaddingTop (), 0 );// width);
854
+ mLeftEdge .setSize (height , width );
855
+
856
+ needsInvalidate = mLeftEdge .draw (canvas );
857
+ canvas .restoreToCount (restoreCount );
858
+ }
859
+
860
+ if (!mTopEdge .isFinished ()) {
861
+ // Log.d("EdgeView", "edge not finished");
862
+ final int restoreCount = canvas .save ();
863
+
864
+ mTopEdge .setSize (width , height );
865
+
866
+ needsInvalidate = mTopEdge .draw (canvas );
867
+ canvas .restoreToCount (restoreCount );
868
+ }
869
+
870
+ if (!mRightEdge .isFinished ()) {
871
+ // Log.d("EdgeView", "edge not finished");
872
+ final int restoreCount = canvas .save ();
873
+
874
+ canvas .rotate (90 );
875
+ canvas .translate (0 , -width );// width);
876
+ mRightEdge .setSize (height , width );
877
+
878
+ needsInvalidate = mRightEdge .draw (canvas );
879
+ canvas .restoreToCount (restoreCount );
880
+ }
881
+
882
+ if (!mBottomEdge .isFinished ()) {
883
+ // Log.d("EdgeView", "edge not finished");
884
+ final int restoreCount = canvas .save ();
885
+
886
+ canvas .rotate (180 );
887
+ canvas .translate (-width + getPaddingTop (), -height );
888
+ mBottomEdge .setSize (height , width );
889
+
890
+ needsInvalidate = mBottomEdge .draw (canvas );
891
+ canvas .restoreToCount (restoreCount );
892
+ }
893
+
894
+ if (needsInvalidate )
895
+ postInvalidateOnAnimation ();
896
+
897
+ }
898
+
808
899
protected void returnItemToPoolIfNeeded (ItemProxy proxy ) {
809
900
View v = proxy .view ;
810
901
v .setTranslationX (0 );
0 commit comments