Skip to content

Commit ffa56a4

Browse files
author
Wu Jing
committed
add scroll rebounce
1 parent b215789 commit ffa56a4

File tree

3 files changed

+44
-20
lines changed

3 files changed

+44
-20
lines changed

app/src/main/res/layout/activity_main.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
android:layout_width="match_parent"
66
android:layout_height="match_parent"
77
app:frv_header="@+id/header"
8-
app:frv_header_expand_height="200dp"
8+
app:frv_header_expand_height="240dp"
99
app:frv_header_height="160dp"
1010
app:frv_header_shrink_height="48dp"
1111
tools:context=".MainActivity">
1212

1313
<FrameLayout
1414
android:id="@id/header"
1515
android:layout_width="match_parent"
16-
android:layout_height="200dp"
16+
android:layout_height="240dp"
1717
android:background="#0099cc"
18-
android:paddingBottom="40dp">
18+
android:paddingBottom="80dp">
1919

2020
<TextView
2121
android:layout_width="wrap_content"

library/src/main/java/com/race604/flyrefresh/FlyRefreshLayout.java

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
package com.race604.flyrefresh;
22

3+
import android.animation.ObjectAnimator;
4+
import android.animation.ValueAnimator;
35
import android.annotation.TargetApi;
46
import android.content.Context;
57
import android.content.res.TypedArray;
8+
import android.graphics.drawable.Drawable;
69
import android.os.Build;
7-
import android.support.v4.view.VelocityTrackerCompat;
810
import android.util.AttributeSet;
9-
import android.util.Log;
1011
import android.view.MotionEvent;
1112
import android.view.VelocityTracker;
1213
import android.view.View;
1314
import android.view.ViewConfiguration;
1415
import android.view.ViewGroup;
15-
import android.widget.AbsListView;
16+
import android.view.animation.AnticipateOvershootInterpolator;
1617
import android.widget.Scroller;
1718

1819
import com.race604.utils.UIUtils;
@@ -300,12 +301,12 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
300301
mHeaderController.onTouchDown(ev.getX(), ev.getY());
301302
offsetY = mHeaderController.getOffsetY();
302303
}
303-
movePos(offsetY);
304+
willMovePos(offsetY);
304305
return true;
305306
}
306307
} else {
307308
if (mHeaderController.canMoveUp()) {
308-
movePos(offsetY);
309+
willMovePos(offsetY);
309310
return true;
310311
} else {
311312
if (mHeaderController.isInTouch()) {
@@ -325,11 +326,11 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
325326
*
326327
* @param deltaY
327328
*/
328-
private void movePos(float deltaY) {
329+
private void willMovePos(float deltaY) {
329330

330331
// has reached the top
331332
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));
333334

334335
if (delta == 0) {
335336
return;
@@ -339,13 +340,33 @@ private void movePos(float deltaY) {
339340
sendCancelEvent();
340341
}
341342

342-
mContent.offsetTopAndBottom(delta);
343+
movePos(delta);
344+
}
345+
346+
private void movePos(float delta) {
347+
mContent.offsetTopAndBottom((int)delta);
343348
}
344349

345350
private void onRelease(int velocity) {
346351
mScrollChecker.tryToScrollTo(velocity);
347352
}
348353

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+
349370
@Override
350371
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
351372
return p instanceof LayoutParams;
@@ -388,7 +409,6 @@ public LayoutParams(ViewGroup.LayoutParams source) {
388409

389410
class ScrollChecker implements Runnable {
390411

391-
private int mLastFlingY;
392412
private Scroller mScroller;
393413
private boolean mIsRunning = false;
394414
private int mStart;
@@ -401,11 +421,10 @@ public ScrollChecker() {
401421
public void run() {
402422
boolean finish = !mScroller.computeScrollOffset() || mScroller.isFinished();
403423
int curY = mScroller.getCurrY();
404-
int deltaY = curY - mStart;
424+
int deltaY = mHeaderController.moveTo(curY);
405425
//Log.d(TAG, String.format("Scroller: currY = %d, deltaY = %d", curY, deltaY));
406426

407427
if (!finish) {
408-
mLastFlingY = curY;
409428
movePos(deltaY);
410429
post(this);
411430
} else {
@@ -415,12 +434,11 @@ public void run() {
415434

416435
private void finish() {
417436
reset();
418-
//onPtrScrollFinish();
437+
onScrollFinish();
419438
}
420439

421440
private void reset() {
422441
mIsRunning = false;
423-
mLastFlingY = 0;
424442
removeCallbacks(this);
425443
}
426444

@@ -438,8 +456,6 @@ public void tryToScrollTo(int velocity) {
438456
mStart = mHeaderController.getCurrentPos();
439457
removeCallbacks(this);
440458

441-
mLastFlingY = mStart;
442-
443459
// fix #47: Scroller should be reused, https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh/issues/47
444460
if (!mScroller.isFinished()) {
445461
mScroller.forceFinished(true);
@@ -452,4 +468,5 @@ public void tryToScrollTo(int velocity) {
452468
mIsRunning = true;
453469
}
454470
}
471+
455472
}

library/src/main/java/com/race604/flyrefresh/HeaderController.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,14 @@ public int willMove(float deltaY) {
111111
return move;
112112
}
113113

114-
public boolean isAlreadyHere(int to) {
115-
return mCurrentPos == to;
114+
public int moveTo(float pos) {
115+
int offsetY = Math.max(mMinHegiht, Math.min(mMaxHegiht, (int)pos));
116+
int delta = offsetY - mCurrentPos;
117+
mCurrentPos = offsetY;
118+
return delta;
119+
}
120+
121+
public boolean isOverHeight() {
122+
return mCurrentPos > mHeight;
116123
}
117124
}

0 commit comments

Comments
 (0)