1
1
package com .race604 .flyrefresh ;
2
2
3
+ import android .animation .ObjectAnimator ;
4
+ import android .animation .ValueAnimator ;
3
5
import android .annotation .TargetApi ;
4
6
import android .content .Context ;
5
7
import android .content .res .TypedArray ;
8
+ import android .graphics .drawable .Drawable ;
6
9
import android .os .Build ;
7
- import android .support .v4 .view .VelocityTrackerCompat ;
8
10
import android .util .AttributeSet ;
9
- import android .util .Log ;
10
11
import android .view .MotionEvent ;
11
12
import android .view .VelocityTracker ;
12
13
import android .view .View ;
13
14
import android .view .ViewConfiguration ;
14
15
import android .view .ViewGroup ;
15
- import android .widget . AbsListView ;
16
+ import android .view . animation . AnticipateOvershootInterpolator ;
16
17
import android .widget .Scroller ;
17
18
18
19
import com .race604 .utils .UIUtils ;
@@ -300,12 +301,12 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
300
301
mHeaderController .onTouchDown (ev .getX (), ev .getY ());
301
302
offsetY = mHeaderController .getOffsetY ();
302
303
}
303
- movePos (offsetY );
304
+ willMovePos (offsetY );
304
305
return true ;
305
306
}
306
307
} else {
307
308
if (mHeaderController .canMoveUp ()) {
308
- movePos (offsetY );
309
+ willMovePos (offsetY );
309
310
return true ;
310
311
} else {
311
312
if (mHeaderController .isInTouch ()) {
@@ -325,11 +326,11 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
325
326
*
326
327
* @param deltaY
327
328
*/
328
- private void movePos (float deltaY ) {
329
+ private void willMovePos (float deltaY ) {
329
330
330
331
// has reached the top
331
332
int delta = mHeaderController .willMove (deltaY );
332
- //Log.d(TAG, String.format("movePos deltaY = %s, delta = %d", deltaY, delta));
333
+ //Log.d(TAG, String.format("willMovePos deltaY = %s, delta = %d", deltaY, delta));
333
334
334
335
if (delta == 0 ) {
335
336
return ;
@@ -339,13 +340,33 @@ private void movePos(float deltaY) {
339
340
sendCancelEvent ();
340
341
}
341
342
342
- mContent .offsetTopAndBottom (delta );
343
+ movePos (delta );
344
+ }
345
+
346
+ private void movePos (float delta ) {
347
+ mContent .offsetTopAndBottom ((int )delta );
343
348
}
344
349
345
350
private void onRelease (int velocity ) {
346
351
mScrollChecker .tryToScrollTo (velocity );
347
352
}
348
353
354
+ private void onScrollFinish () {
355
+ if (mHeaderController .isOverHeight ()) {
356
+ ValueAnimator bounceAnim = ObjectAnimator .ofFloat (mHeaderController .getCurrentPos (), mHeaderController .getHeight ());
357
+ bounceAnim .setInterpolator (new AnticipateOvershootInterpolator ());
358
+ bounceAnim .setDuration (500 );
359
+ bounceAnim .addUpdateListener (new ValueAnimator .AnimatorUpdateListener () {
360
+ @ Override
361
+ public void onAnimationUpdate (ValueAnimator animation ) {
362
+ float value = (float ) animation .getAnimatedValue ();
363
+ movePos (mHeaderController .moveTo (value ));
364
+ }
365
+ });
366
+ bounceAnim .start ();
367
+ }
368
+ }
369
+
349
370
@ Override
350
371
protected boolean checkLayoutParams (ViewGroup .LayoutParams p ) {
351
372
return p instanceof LayoutParams ;
@@ -388,7 +409,6 @@ public LayoutParams(ViewGroup.LayoutParams source) {
388
409
389
410
class ScrollChecker implements Runnable {
390
411
391
- private int mLastFlingY ;
392
412
private Scroller mScroller ;
393
413
private boolean mIsRunning = false ;
394
414
private int mStart ;
@@ -401,11 +421,10 @@ public ScrollChecker() {
401
421
public void run () {
402
422
boolean finish = !mScroller .computeScrollOffset () || mScroller .isFinished ();
403
423
int curY = mScroller .getCurrY ();
404
- int deltaY = curY - mStart ;
424
+ int deltaY = mHeaderController . moveTo ( curY ) ;
405
425
//Log.d(TAG, String.format("Scroller: currY = %d, deltaY = %d", curY, deltaY));
406
426
407
427
if (!finish ) {
408
- mLastFlingY = curY ;
409
428
movePos (deltaY );
410
429
post (this );
411
430
} else {
@@ -415,12 +434,11 @@ public void run() {
415
434
416
435
private void finish () {
417
436
reset ();
418
- //onPtrScrollFinish ();
437
+ onScrollFinish ();
419
438
}
420
439
421
440
private void reset () {
422
441
mIsRunning = false ;
423
- mLastFlingY = 0 ;
424
442
removeCallbacks (this );
425
443
}
426
444
@@ -438,8 +456,6 @@ public void tryToScrollTo(int velocity) {
438
456
mStart = mHeaderController .getCurrentPos ();
439
457
removeCallbacks (this );
440
458
441
- mLastFlingY = mStart ;
442
-
443
459
// fix #47: Scroller should be reused, https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh/issues/47
444
460
if (!mScroller .isFinished ()) {
445
461
mScroller .forceFinished (true );
@@ -452,4 +468,5 @@ public void tryToScrollTo(int velocity) {
452
468
mIsRunning = true ;
453
469
}
454
470
}
471
+
455
472
}
0 commit comments