Skip to content

Commit d0a21c0

Browse files
committed
optimize pull to refresh
1 parent 79721ab commit d0a21c0

File tree

3 files changed

+59
-32
lines changed

3 files changed

+59
-32
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ buildscript {
55
jcenter()
66
}
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:1.0.0'
8+
classpath 'com.android.tools.build:gradle:1.3.0'
99

1010
// NOTE: Do not place your application dependencies here; they belong
1111
// in the individual module build.gradle files

library/src/main/java/com/baoyz/widget/PullRefreshLayout.java

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.support.v4.view.MotionEventCompat;
66
import android.support.v4.view.ViewCompat;
77
import android.util.AttributeSet;
8+
import android.util.Log;
89
import android.util.TypedValue;
910
import android.view.MotionEvent;
1011
import android.view.View;
@@ -56,6 +57,7 @@ public class PullRefreshLayout extends ViewGroup {
5657

5758
public int mDurationToStartPosition;
5859
public int mDurationToCorrectPosition;
60+
private int mInitialOffsetTop;
5961

6062
public PullRefreshLayout(Context context) {
6163
this(context, null);
@@ -86,14 +88,14 @@ public PullRefreshLayout(Context context, AttributeSet attrs) {
8688
ViewCompat.setChildrenDrawingOrderEnabled(this, true);
8789
}
8890

89-
public void setColorSchemeColors(int[] colorSchemeColors){
91+
public void setColorSchemeColors(int[] colorSchemeColors) {
9092
mColorSchemeColors = colorSchemeColors;
9193
mRefreshDrawable.setColorSchemeColors(colorSchemeColors);
9294
}
9395

94-
public void setRefreshStyle(int type){
96+
public void setRefreshStyle(int type) {
9597
setRefreshing(false);
96-
switch (type){
98+
switch (type) {
9799
case STYLE_MATERIAL:
98100
mRefreshDrawable = new MaterialDrawable(getContext(), this);
99101
break;
@@ -113,14 +115,14 @@ public void setRefreshStyle(int type){
113115
mRefreshView.setImageDrawable(mRefreshDrawable);
114116
}
115117

116-
public void setRefreshDrawable(RefreshDrawable drawable){
118+
public void setRefreshDrawable(RefreshDrawable drawable) {
117119
setRefreshing(false);
118120
mRefreshDrawable = drawable;
119121
mRefreshDrawable.setColorSchemeColors(mColorSchemeColors);
120122
mRefreshView.setImageDrawable(mRefreshDrawable);
121123
}
122124

123-
public int getFinalOffset(){
125+
public int getFinalOffset() {
124126
return mSpinnerFinalOffset;
125127
}
126128

@@ -154,22 +156,30 @@ private void ensureTarget() {
154156
@Override
155157
public boolean onInterceptTouchEvent(MotionEvent ev) {
156158

157-
if (!isEnabled() || canChildScrollUp() || mRefreshing) {
159+
if (!isEnabled() || canChildScrollUp()) {
158160
return false;
159161
}
160162

163+
// if (mRefreshing) {
164+
// Log.d("byz", "mCurrentOffsetTop " + mCurrentOffsetTop);
165+
// return mCurrentOffsetTop > 0;
166+
// }
167+
161168
final int action = MotionEventCompat.getActionMasked(ev);
162169

163170
switch (action) {
164171
case MotionEvent.ACTION_DOWN:
165-
setTargetOffsetTop(0, true);
172+
if (!mRefreshing) {
173+
setTargetOffsetTop(0, true);
174+
}
166175
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
167176
mIsBeingDragged = false;
168177
final float initialMotionY = getMotionEventY(ev, mActivePointerId);
169178
if (initialMotionY == -1) {
170179
return false;
171180
}
172181
mInitialMotionY = initialMotionY;
182+
mInitialOffsetTop = mCurrentOffsetTop;
173183
break;
174184
case MotionEvent.ACTION_MOVE:
175185
if (mActivePointerId == INVALID_POINTER) {
@@ -184,7 +194,14 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
184194
// mIsBeingDragged = true;
185195
// mMode = yDiff > 0 ? MODE_TOP : MODE_BOTTOM;
186196
// }
187-
if (yDiff > mTouchSlop && !mIsBeingDragged) {
197+
if (mRefreshing) {
198+
mIsBeingDragged = !(yDiff < 0 && mCurrentOffsetTop <= 0);
199+
// if (yDiff > 0) {
200+
// mIsBeingDragged = mCurrentOffsetTop <= 0;
201+
// } else {
202+
// mIsBeingDragged = mCurrentOffsetTop >= 0;
203+
// }
204+
} else if (yDiff > mTouchSlop && !mIsBeingDragged) {
188205
mIsBeingDragged = true;
189206
}
190207
break;
@@ -220,27 +237,37 @@ public boolean onTouchEvent(MotionEvent ev) {
220237
final float y = MotionEventCompat.getY(ev, pointerIndex);
221238
// final float yDiff = Math.abs(y - mInitialMotionY);
222239
final float yDiff = y - mInitialMotionY;
223-
final float scrollTop = yDiff * DRAG_RATE;
224-
float originalDragPercent = scrollTop / mTotalDragDistance;
225-
if (originalDragPercent < 0) {
226-
return false;
227-
}
228-
float dragPercent = Math.min(1f, Math.abs(originalDragPercent));
240+
int targetY;
241+
if (mRefreshing) {
242+
targetY = (int) (mInitialOffsetTop + yDiff);
243+
if (targetY < 0) {
244+
targetY = 0;
245+
} else if (targetY > mTotalDragDistance) {
246+
targetY = mTotalDragDistance;
247+
}
248+
} else {
249+
final float scrollTop = yDiff * DRAG_RATE;
250+
float originalDragPercent = scrollTop / mTotalDragDistance;
251+
if (originalDragPercent < 0) {
252+
return false;
253+
}
254+
float dragPercent = Math.min(1f, Math.abs(originalDragPercent));
229255
// float adjustedPercent = (float) Math.max(dragPercent - .4, 0) * 5 / 3;
230256
// float adjustedPercent = dragPercent;
231-
float extraOS = Math.abs(scrollTop) - mTotalDragDistance;
232-
float slingshotDist = mSpinnerFinalOffset;
233-
float tensionSlingshotPercent = Math.max(0,
234-
Math.min(extraOS, slingshotDist * 2) / slingshotDist);
235-
float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow(
236-
(tensionSlingshotPercent / 4), 2)) * 2f;
237-
float extraMove = (slingshotDist) * tensionPercent * 2;
238-
int targetY = (int) ((slingshotDist * dragPercent) + extraMove);
239-
if (mRefreshView.getVisibility() != View.VISIBLE) {
240-
mRefreshView.setVisibility(View.VISIBLE);
241-
}
242-
if (scrollTop < mTotalDragDistance) {
243-
mRefreshDrawable.setPercent(dragPercent);
257+
float extraOS = Math.abs(scrollTop) - mTotalDragDistance;
258+
float slingshotDist = mSpinnerFinalOffset;
259+
float tensionSlingshotPercent = Math.max(0,
260+
Math.min(extraOS, slingshotDist * 2) / slingshotDist);
261+
float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow(
262+
(tensionSlingshotPercent / 4), 2)) * 2f;
263+
float extraMove = (slingshotDist) * tensionPercent * 2;
264+
targetY = (int) ((slingshotDist * dragPercent) + extraMove);
265+
if (mRefreshView.getVisibility() != View.VISIBLE) {
266+
mRefreshView.setVisibility(View.VISIBLE);
267+
}
268+
if (scrollTop < mTotalDragDistance) {
269+
mRefreshDrawable.setPercent(dragPercent);
270+
}
244271
}
245272
setTargetOffsetTop(targetY - mCurrentOffsetTop, true);
246273
break;
@@ -254,7 +281,7 @@ public boolean onTouchEvent(MotionEvent ev) {
254281
break;
255282
case MotionEvent.ACTION_UP:
256283
case MotionEvent.ACTION_CANCEL: {
257-
if (mActivePointerId == INVALID_POINTER) {
284+
if (mActivePointerId == INVALID_POINTER || mRefreshing) {
258285
return false;
259286
}
260287
final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
@@ -410,8 +437,8 @@ private void setTargetOffsetTop(int offset, boolean requiresUpdate) {
410437
mRefreshView.bringToFront();
411438
// mRefreshView.offsetTopAndBottom(offset);
412439
mTarget.offsetTopAndBottom(offset);
413-
mRefreshDrawable.offsetTopAndBottom(offset);
414440
mCurrentOffsetTop = mTarget.getTop();
441+
mRefreshDrawable.offsetTopAndBottom(offset);
415442
if (requiresUpdate && android.os.Build.VERSION.SDK_INT < 11) {
416443
invalidate();
417444
}
@@ -461,7 +488,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
461488
int right = getPaddingRight();
462489
int bottom = getPaddingBottom();
463490

464-
mTarget.layout(left, top + mCurrentOffsetTop, left + width - right, top + height - bottom + mCurrentOffsetTop);
491+
mTarget.layout(left, top + mTarget.getTop(), left + width - right, top + height - bottom + mTarget.getTop());
465492
// mRefreshView.layout(width / 2 - mRefreshViewWidth / 2, -mRefreshViewHeight + mCurrentOffsetTop, width / 2 + mRefreshViewHeight / 2, mCurrentOffsetTop);
466493
mRefreshView.layout(left, top, left + width - right, top + height - bottom);
467494
}

sample/src/main/java/com/baoyz/pullrefreshlayout/sample/DemoActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void onRefresh() {
4141
public void run() {
4242
layout.setRefreshing(false);
4343
}
44-
}, 4000);
44+
}, 10000);
4545
}
4646
});
4747
}

0 commit comments

Comments
 (0)