@@ -110,6 +110,11 @@ private enum Direction {
110
110
private int mScaledTouchSlop = 0 ;
111
111
private EventRect mNewEventRect ;
112
112
private TextColorPicker textColorPicker ;
113
+ private float mSizeOfWeekView ;
114
+ private float mDistanceDone = 0 ;
115
+ private float mDistanceMin ;
116
+ protected int mOffsetValueToSecureScreen = 9 ;
117
+ private float mStartOriginForScroll = 0 ;
113
118
114
119
// Attributes and their default values.
115
120
private int mHourHeight = 50 ;
@@ -118,7 +123,7 @@ private enum Direction {
118
123
private int mEffectiveMinHourHeight = mMinHourHeight ; //compensates for the fact that you can't keep zooming out.
119
124
private int mMaxHourHeight = 250 ;
120
125
private int mColumnGap = 10 ;
121
- private int mFirstDayOfWeek = Calendar .MONDAY ;
126
+ private int mFirstDayOfWeek = Calendar .getInstance (). getFirstDayOfWeek () ;
122
127
private int mTextSize = 12 ;
123
128
private int mHeaderColumnPadding = 10 ;
124
129
private int mHeaderColumnTextColor = Color .BLACK ;
@@ -174,6 +179,7 @@ private enum Direction {
174
179
private boolean mAutoLimitTime = false ;
175
180
private boolean mEnableDropListener = false ;
176
181
private int mMinOverlappingMinutes = 0 ;
182
+ private boolean mIsScrollNumberOfVisibleDays = false ;
177
183
178
184
// Listeners.
179
185
private EventClickListener mEventClickListener ;
@@ -190,6 +196,7 @@ private enum Direction {
190
196
191
197
@ Override
192
198
public boolean onDown (MotionEvent e ) {
199
+ mStartOriginForScroll = mCurrentOrigin .x ;
193
200
goToNearestOrigin ();
194
201
return true ;
195
202
}
@@ -238,6 +245,13 @@ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float d
238
245
case RIGHT :
239
246
float minX = getXMinLimit ();
240
247
float maxX = getXMaxLimit ();
248
+
249
+ if (e2 .getX () < 0 ) {
250
+ mDistanceDone = e2 .getX () - e1 .getX ();
251
+ } else {
252
+ mDistanceDone = e1 .getX () - e2 .getX ();
253
+ }
254
+
241
255
if ((mCurrentOrigin .x - (distanceX * mXScrollingSpeed )) > maxX ) {
242
256
mCurrentOrigin .x = maxX ;
243
257
} else if ((mCurrentOrigin .x - (distanceX * mXScrollingSpeed )) < minX ) {
@@ -282,7 +296,9 @@ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float ve
282
296
switch (mCurrentFlingDirection ) {
283
297
case LEFT :
284
298
case RIGHT :
285
- mScroller .fling ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , (int ) (velocityX * mXScrollingSpeed ), 0 , (int ) getXMinLimit (), (int ) getXMaxLimit (), (int ) getYMinLimit (), (int ) getYMaxLimit ());
299
+ if (!mIsScrollNumberOfVisibleDays ) {
300
+ mScroller .fling ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , (int ) (velocityX * mXScrollingSpeed ), 0 , (int ) getXMinLimit (), (int ) getXMaxLimit (), (int ) getYMinLimit (), (int ) getYMaxLimit ());
301
+ }
286
302
break ;
287
303
case VERTICAL :
288
304
mScroller .fling ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , 0 , (int ) velocityY , (int ) getXMinLimit (), (int ) getXMaxLimit (), (int ) getYMinLimit (), (int ) getYMaxLimit ());
@@ -494,6 +510,7 @@ public WeekView(Context context, AttributeSet attrs, int defStyleAttr) {
494
510
if (a .getBoolean (R .styleable .WeekView_dropListenerEnabled , false ))
495
511
this .enableDropListener ();
496
512
mMinOverlappingMinutes = a .getInt (R .styleable .WeekView_minOverlappingMinutes , 0 );
513
+ mIsScrollNumberOfVisibleDays = a .getBoolean (R .styleable .WeekView_isScrollNumberOfVisibleDays , false );
497
514
} finally {
498
515
a .recycle ();
499
516
}
@@ -2517,6 +2534,15 @@ public int getMinOverlappingMinutes() {
2517
2534
return this .mMinOverlappingMinutes ;
2518
2535
}
2519
2536
2537
+ public boolean isScrollNumberOfVisibleDays () {
2538
+ return this .mIsScrollNumberOfVisibleDays ;
2539
+ }
2540
+
2541
+ public void setScrollNumberOfVisibleDays (boolean scrollNumberOfVisibleDays ) {
2542
+ this .mIsScrollNumberOfVisibleDays = scrollNumberOfVisibleDays ;
2543
+ invalidate ();
2544
+ }
2545
+
2520
2546
/////////////////////////////////////////////////////////////////
2521
2547
//
2522
2548
// Functions related to scrolling.
@@ -2525,6 +2551,10 @@ public int getMinOverlappingMinutes() {
2525
2551
2526
2552
@ Override
2527
2553
public boolean onTouchEvent (MotionEvent event ) {
2554
+
2555
+ mSizeOfWeekView = (mWidthPerDay + mColumnGap ) * getNumberOfVisibleDays ();
2556
+ mDistanceMin = mSizeOfWeekView / mOffsetValueToSecureScreen ;
2557
+
2528
2558
mScaleDetector .onTouchEvent (event );
2529
2559
boolean val = mGestureDetector .onTouchEvent (event );
2530
2560
@@ -2542,41 +2572,78 @@ public boolean onTouchEvent(MotionEvent event) {
2542
2572
private void goToNearestOrigin () {
2543
2573
double leftDays = mCurrentOrigin .x / (mWidthPerDay + mColumnGap );
2544
2574
2545
- if (mCurrentFlingDirection != Direction .NONE ) {
2546
- // snap to nearest day
2547
- leftDays = Math .round (leftDays );
2548
- } else if (mCurrentScrollDirection == Direction .LEFT ) {
2549
- // snap to last day
2550
- leftDays = Math .floor (leftDays );
2551
- } else if (mCurrentScrollDirection == Direction .RIGHT ) {
2552
- // snap to next day
2553
- leftDays = Math .ceil (leftDays );
2554
- } else {
2555
- // snap to nearest day
2556
- leftDays = Math .round (leftDays );
2557
- }
2575
+ float beforeScroll = mStartOriginForScroll ;
2576
+ boolean isPassed = false ;
2577
+
2578
+ if (mDistanceDone > mDistanceMin || mDistanceDone < -mDistanceMin || !mIsScrollNumberOfVisibleDays ) {
2579
+
2580
+ if (!mIsScrollNumberOfVisibleDays && mCurrentFlingDirection != Direction .NONE ) {
2581
+ // snap to nearest day
2582
+ leftDays = Math .round (leftDays );
2583
+ } else if (mCurrentScrollDirection == Direction .LEFT ) {
2584
+ // snap to last day
2585
+ leftDays = Math .floor (leftDays );
2586
+ mStartOriginForScroll -= mSizeOfWeekView ;
2587
+ isPassed = true ;
2588
+ } else if (mCurrentScrollDirection == Direction .RIGHT ) {
2589
+ // snap to next day
2590
+ leftDays = Math .floor (leftDays );
2591
+ mStartOriginForScroll += mSizeOfWeekView ;
2592
+ isPassed = true ;
2593
+ } else {
2594
+ // snap to nearest day
2595
+ leftDays = Math .round (leftDays );
2596
+ }
2558
2597
2559
- int nearestOrigin = (int ) (mCurrentOrigin .x - leftDays * (mWidthPerDay + mColumnGap ));
2560
- boolean mayScrollHorizontal = mCurrentOrigin .x - nearestOrigin < getXMaxLimit ()
2561
- && mCurrentOrigin .x - nearestOrigin > getXMinLimit ();
2562
2598
2563
- if (mayScrollHorizontal ) {
2564
- mScroller .startScroll ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , -nearestOrigin , 0 );
2565
- ViewCompat .postInvalidateOnAnimation (WeekView .this );
2566
- }
2599
+ if (mIsScrollNumberOfVisibleDays ) {
2600
+ boolean mayScrollHorizontal = beforeScroll - mStartOriginForScroll < getXMaxLimit () && mCurrentOrigin .x - mStartOriginForScroll > getXMinLimit ();
2601
+ if (isPassed && mayScrollHorizontal ) {
2602
+ // Stop current animation.
2603
+ mScroller .forceFinished (true );
2604
+ // Snap to date.
2605
+ if (mCurrentScrollDirection == Direction .LEFT ) {
2606
+ mScroller .startScroll ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , (int ) ((beforeScroll - mCurrentOrigin .x ) - mSizeOfWeekView ), 0 , 200 );
2607
+ } else if (mCurrentScrollDirection == Direction .RIGHT ) {
2608
+ mScroller .startScroll ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , (int ) (mSizeOfWeekView - (mCurrentOrigin .x - beforeScroll )), 0 , 200 );
2609
+ }
2610
+ ViewCompat .postInvalidateOnAnimation (WeekView .this );
2611
+ }
2612
+ } else {
2613
+ int nearestOrigin = (int ) (mCurrentOrigin .x - leftDays * (mWidthPerDay + mColumnGap ));
2614
+ boolean mayScrollHorizontal = mCurrentOrigin .x - nearestOrigin < getXMaxLimit () && mCurrentOrigin .x - nearestOrigin > getXMinLimit ();
2615
+ if (mayScrollHorizontal ) {
2616
+ mScroller .startScroll ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , -nearestOrigin , 0 );
2617
+ ViewCompat .postInvalidateOnAnimation (WeekView .this );
2618
+ }
2567
2619
2568
- if (nearestOrigin != 0 && mayScrollHorizontal ) {
2569
- // Stop current animation.
2620
+ if (nearestOrigin != 0 && mayScrollHorizontal ) {
2621
+ // Stop current animation.
2622
+ mScroller .forceFinished (true );
2623
+ // Snap to date.
2624
+ mScroller .startScroll ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , -nearestOrigin , 0 , (int ) (Math .abs (nearestOrigin ) / mWidthPerDay * mScrollDuration ));
2625
+ ViewCompat .postInvalidateOnAnimation (WeekView .this );
2626
+ }
2627
+ }
2628
+
2629
+ // Reset scrolling and fling direction.
2630
+ mCurrentScrollDirection = mCurrentFlingDirection = Direction .NONE ;
2631
+
2632
+
2633
+ } else {
2570
2634
mScroller .forceFinished (true );
2571
- // Snap to date.
2572
- mScroller .startScroll ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , -nearestOrigin , 0 , (int ) (Math .abs (nearestOrigin ) / mWidthPerDay * mScrollDuration ));
2635
+ if (mCurrentScrollDirection == Direction .LEFT ) {
2636
+ mScroller .startScroll ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , (int ) beforeScroll - (int ) mCurrentOrigin .x , 0 , 200 );
2637
+ } else if (mCurrentScrollDirection == Direction .RIGHT ) {
2638
+ mScroller .startScroll ((int ) mCurrentOrigin .x , (int ) mCurrentOrigin .y , (int ) beforeScroll - (int ) mCurrentOrigin .x , 0 , 200 );
2639
+ }
2573
2640
ViewCompat .postInvalidateOnAnimation (WeekView .this );
2641
+
2642
+ // Reset scrolling and fling direction.
2643
+ mCurrentScrollDirection = mCurrentFlingDirection = Direction .NONE ;
2574
2644
}
2575
- // Reset scrolling and fling direction.
2576
- mCurrentScrollDirection = mCurrentFlingDirection = Direction .NONE ;
2577
2645
}
2578
2646
2579
-
2580
2647
@ Override
2581
2648
public void computeScroll () {
2582
2649
super .computeScroll ();
0 commit comments