From 393e85ecc975a5592770896801ba0f99e6893ba0 Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Wed, 23 Sep 2015 19:57:22 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E4=B8=8A=E6=8B=89?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=9B=B4=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/baoyz/widget/ArcDrawable.java | 2 +- .../com/baoyz/widget/CirclesDrawable.java | 2 +- .../com/baoyz/widget/MaterialDrawable.java | 2 +- .../com/baoyz/widget/PullRefreshLayout.java | 158 +++++++++++------- .../com/baoyz/widget/RefreshDrawable.java | 26 ++- .../java/com/baoyz/widget/RingDrawable.java | 2 +- .../com/baoyz/widget/SmartisanDrawable.java | 3 +- .../com/baoyz/widget/WaterDropDrawable.java | 2 +- .../sample/ScrollViewActivity.java | 2 +- 9 files changed, 134 insertions(+), 65 deletions(-) diff --git a/library/src/main/java/com/baoyz/widget/ArcDrawable.java b/library/src/main/java/com/baoyz/widget/ArcDrawable.java index 72a2fb2..9d2e2e0 100644 --- a/library/src/main/java/com/baoyz/widget/ArcDrawable.java +++ b/library/src/main/java/com/baoyz/widget/ArcDrawable.java @@ -110,7 +110,7 @@ protected void onBoundsChange(Rect bounds) { } @Override - public void draw(Canvas canvas) { + public void onDraw(Canvas canvas) { canvas.save(); // canvas.translate(0, mTop); drawRing(canvas); diff --git a/library/src/main/java/com/baoyz/widget/CirclesDrawable.java b/library/src/main/java/com/baoyz/widget/CirclesDrawable.java index d495aee..31550b5 100644 --- a/library/src/main/java/com/baoyz/widget/CirclesDrawable.java +++ b/library/src/main/java/com/baoyz/widget/CirclesDrawable.java @@ -198,7 +198,7 @@ private void resetColor(ProgressStates currentState) { } @Override - public void draw(Canvas canvas) { + public void onDraw(Canvas canvas) { if (mCurrentState != null) { canvas.save(); canvas.translate(mBounds.width() / 2 - mDrawWidth / 2, mTop); diff --git a/library/src/main/java/com/baoyz/widget/MaterialDrawable.java b/library/src/main/java/com/baoyz/widget/MaterialDrawable.java index c67661b..742c7ed 100644 --- a/library/src/main/java/com/baoyz/widget/MaterialDrawable.java +++ b/library/src/main/java/com/baoyz/widget/MaterialDrawable.java @@ -326,7 +326,7 @@ public void offsetTopAndBottom(int offset) { // } @Override - public void draw(Canvas c) { + public void onDraw(Canvas c) { Rect bounds = getBounds(); final int saveCount = c.save(); c.translate(0, mTop); diff --git a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java index 5fcefc0..f1d2f52 100644 --- a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java +++ b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java @@ -6,6 +6,7 @@ import android.support.v4.view.MotionEventCompat; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; +import android.util.Log; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; @@ -36,6 +37,9 @@ public class PullRefreshLayout extends ViewGroup { public static final int STYLE_RING = 3; public static final int STYLE_SMARTISAN = 4; + public static final int DIRECTION_UP = -1; + public static final int DIRECTION_DOWN = 1; + private View mTarget; private ImageView mRefreshView; private Interpolator mDecelerateInterpolator; @@ -58,6 +62,7 @@ public class PullRefreshLayout extends ViewGroup { private int mInitialOffsetTop; private boolean mDispatchTargetTouchDown; private float mDragPercent; + private int mScrollDirection; public PullRefreshLayout(Context context) { this(context, null); @@ -171,7 +176,7 @@ private void ensureTarget() { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (!isEnabled() || (canChildScrollUp() && !mRefreshing)) { + if (!isEnabled()) { return false; } @@ -179,9 +184,9 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { switch (action) { case MotionEvent.ACTION_DOWN: - if (!mRefreshing) { - setTargetOffsetTop(0, true); - } +// if (!mRefreshing) { +// setTargetOffsetTop(0, true); +// } mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mIsBeingDragged = false; final float initialMotionY = getMotionEventY(ev, mActivePointerId); @@ -201,11 +206,21 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { if (y == -1) { return false; } - final float yDiff = y - mInitialMotionY; + float yDiff = y - mInitialMotionY; if (mRefreshing) { + yDiff = mScrollDirection == DIRECTION_UP ? y - mInitialMotionY : mInitialMotionY - y; mIsBeingDragged = !(yDiff < 0 && mCurrentOffsetTop <= 0); - } else if (yDiff > mTouchSlop && !mIsBeingDragged) { - mIsBeingDragged = true; + } else if (Math.abs(yDiff) > mTouchSlop && !mIsBeingDragged) { + if (yDiff > 0) { + // scroll up + mIsBeingDragged = !canChildScrollUp(); + mScrollDirection = DIRECTION_UP; + } else { + // scroll down + mIsBeingDragged = !canChildScrollDown(); + mScrollDirection = DIRECTION_DOWN; + } + mRefreshDrawable.setDirection(mScrollDirection); } break; case MotionEvent.ACTION_UP: @@ -238,11 +253,11 @@ public boolean onTouchEvent(MotionEvent ev) { } final float y = MotionEventCompat.getY(ev, pointerIndex); - final float yDiff = y - mInitialMotionY; + final float yDiff = mScrollDirection == DIRECTION_UP ? y - mInitialMotionY : mInitialMotionY - y; int targetY; if (mRefreshing) { targetY = (int) (mInitialOffsetTop + yDiff); - if (canChildScrollUp()) { + if (canChildScroll()) { targetY = -1; mInitialMotionY = y; mInitialOffsetTop = 0; @@ -322,9 +337,9 @@ public boolean onTouchEvent(MotionEvent ev) { } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float y = MotionEventCompat.getY(ev, pointerIndex); - final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; + final float overScrollTop = (mScrollDirection == DIRECTION_UP ? y - mInitialMotionY : mInitialMotionY - y) * DRAG_RATE; mIsBeingDragged = false; - if (overscrollTop > mTotalDragDistance) { + if (overScrollTop > mTotalDragDistance) { setRefreshing(true, true); } else { mRefreshing = false; @@ -338,6 +353,72 @@ public boolean onTouchEvent(MotionEvent ev) { return true; } + private void setTargetOffsetTop(int offset, boolean requiresUpdate) { + if (mScrollDirection == DIRECTION_DOWN) { + mTarget.offsetTopAndBottom(-offset); + mRefreshDrawable.offsetTopAndBottom(offset); + } else { + mTarget.offsetTopAndBottom(offset); + mRefreshDrawable.offsetTopAndBottom(offset); + } + mCurrentOffsetTop = getTargetTop(); + + if (requiresUpdate && android.os.Build.VERSION.SDK_INT < 11) { + invalidate(); + } + } + + private void onSecondaryPointerUp(MotionEvent ev) { + final int pointerIndex = MotionEventCompat.getActionIndex(ev); + final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); + if (pointerId == mActivePointerId) { + final int newPointerIndex = pointerIndex == 0 ? 1 : 0; + mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex); + } + } + + private float getMotionEventY(MotionEvent ev, int activePointerId) { + final int index = MotionEventCompat.findPointerIndex(ev, activePointerId); + if (index < 0) { + return -1; + } + return MotionEventCompat.getY(ev, index); + } + + private boolean canChildScroll(){ + return mScrollDirection == DIRECTION_UP ? canChildScrollUp() : canChildScrollDown(); + } + + private boolean canChildScrollUp() { + if (android.os.Build.VERSION.SDK_INT < 14) { + if (mTarget instanceof AbsListView) { + final AbsListView absListView = (AbsListView) mTarget; + return absListView.getChildCount() > 0 + && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) + .getTop() < absListView.getPaddingTop()); + } else { + return mTarget.getScrollY() > 0; + } + } else { + return ViewCompat.canScrollVertically(mTarget, DIRECTION_UP); + } + } + + private boolean canChildScrollDown() { + if (android.os.Build.VERSION.SDK_INT < 14) { + if (mTarget instanceof AbsListView) { + final AbsListView absListView = (AbsListView) mTarget; + return absListView.getChildCount() > 0 + && (absListView.getLastVisiblePosition() < (absListView.getCount() - 1) || absListView.getChildAt((absListView.getCount() - 1)) + .getBottom() < absListView.getPaddingBottom()); + } else { + return mTarget.getScrollY() > 0; + } + } else { + return ViewCompat.canScrollVertically(mTarget, DIRECTION_DOWN); + } + } + public void setDurations(int durationToStartPosition, int durationToCorrectPosition) { mDurationToStartPosition = durationToStartPosition; mDurationToCorrectPosition = durationToCorrectPosition; @@ -375,18 +456,23 @@ public void applyTransformation(float interpolatedTime, Transformation t) { public void applyTransformation(float interpolatedTime, Transformation t) { int endTarget = mSpinnerFinalOffset; int targetTop = (mFrom + (int) ((endTarget - mFrom) * interpolatedTime)); - int offset = targetTop - mTarget.getTop(); + int offset = targetTop - getTargetTop(); setTargetOffsetTop(offset, false /* requires update */); } }; private void moveToStart(float interpolatedTime) { int targetTop = mFrom - (int) (mFrom * interpolatedTime); - int offset = targetTop - mTarget.getTop(); + int offset = targetTop - getTargetTop(); setTargetOffsetTop(offset, false); mRefreshDrawable.setPercent(mDragPercent * (1 - interpolatedTime)); } + private int getTargetTop(){ + return mScrollDirection == DIRECTION_UP ? mTarget.getTop() : -mTarget.getTop(); +// return mTarget.getTop(); + } + public void setRefreshing(boolean refreshing) { if (mRefreshing != refreshing) { setRefreshing(refreshing, false /* notify */); @@ -431,7 +517,7 @@ public void onAnimationEnd(Animation animation) { mRefreshView.setVisibility(View.GONE); animateOffsetToStartPosition(); } - mCurrentOffsetTop = mTarget.getTop(); + mCurrentOffsetTop = getTargetTop(); } }; @@ -449,52 +535,10 @@ public void onAnimationRepeat(Animation animation) { public void onAnimationEnd(Animation animation) { // mRefreshDrawable.stop(); mRefreshView.setVisibility(View.GONE); - mCurrentOffsetTop = mTarget.getTop(); + mCurrentOffsetTop = getTargetTop(); } }; - private void onSecondaryPointerUp(MotionEvent ev) { - final int pointerIndex = MotionEventCompat.getActionIndex(ev); - final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); - if (pointerId == mActivePointerId) { - final int newPointerIndex = pointerIndex == 0 ? 1 : 0; - mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex); - } - } - - private float getMotionEventY(MotionEvent ev, int activePointerId) { - final int index = MotionEventCompat.findPointerIndex(ev, activePointerId); - if (index < 0) { - return -1; - } - return MotionEventCompat.getY(ev, index); - } - - private void setTargetOffsetTop(int offset, boolean requiresUpdate) { -// mRefreshView.bringToFront(); - mTarget.offsetTopAndBottom(offset); - mCurrentOffsetTop = mTarget.getTop(); - mRefreshDrawable.offsetTopAndBottom(offset); - if (requiresUpdate && android.os.Build.VERSION.SDK_INT < 11) { - invalidate(); - } - } - - private boolean canChildScrollUp() { - if (android.os.Build.VERSION.SDK_INT < 14) { - if (mTarget instanceof AbsListView) { - final AbsListView absListView = (AbsListView) mTarget; - return absListView.getChildCount() > 0 - && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) - .getTop() < absListView.getPaddingTop()); - } else { - return mTarget.getScrollY() > 0; - } - } else { - return ViewCompat.canScrollVertically(mTarget, -1); - } - } - @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { diff --git a/library/src/main/java/com/baoyz/widget/RefreshDrawable.java b/library/src/main/java/com/baoyz/widget/RefreshDrawable.java index 5acbf0c..cde0b96 100644 --- a/library/src/main/java/com/baoyz/widget/RefreshDrawable.java +++ b/library/src/main/java/com/baoyz/widget/RefreshDrawable.java @@ -1,8 +1,10 @@ package com.baoyz.widget; import android.content.Context; +import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.PixelFormat; +import android.graphics.Rect; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; @@ -12,6 +14,8 @@ public abstract class RefreshDrawable extends Drawable implements Drawable.Callback, Animatable { private PullRefreshLayout mRefreshLayout; + private Rect mOriginBounds; + private int mDirection; public RefreshDrawable(Context context, PullRefreshLayout layout) { mRefreshLayout = layout; @@ -27,8 +31,28 @@ public PullRefreshLayout getRefreshLayout(){ public abstract void setPercent(float percent); public abstract void setColorSchemeColors(int[] colorSchemeColors); - public abstract void offsetTopAndBottom(int offset); + public void setDirection(int direction) { + mDirection = direction; + } + + @Override + public final void draw(Canvas canvas) { + int save = canvas.save(); + if (mDirection == PullRefreshLayout.DIRECTION_DOWN) { + canvas.rotate(180, mOriginBounds.centerX(), mOriginBounds.centerY()); + } + onDraw(canvas); + canvas.restoreToCount(save); + } + + public abstract void onDraw(Canvas canvas); + + @Override + protected void onBoundsChange(Rect bounds) { + super.onBoundsChange(bounds); + mOriginBounds = bounds; + } @Override public void invalidateDrawable(Drawable who) { diff --git a/library/src/main/java/com/baoyz/widget/RingDrawable.java b/library/src/main/java/com/baoyz/widget/RingDrawable.java index deabbc5..e6b9d90 100644 --- a/library/src/main/java/com/baoyz/widget/RingDrawable.java +++ b/library/src/main/java/com/baoyz/widget/RingDrawable.java @@ -94,7 +94,7 @@ protected void onBoundsChange(Rect bounds) { } @Override - public void draw(Canvas canvas) { + public void onDraw(Canvas canvas) { canvas.save(); // canvas.translate(0, mTop); canvas.rotate(mDegress, mBounds.centerX(), mBounds.centerY()); diff --git a/library/src/main/java/com/baoyz/widget/SmartisanDrawable.java b/library/src/main/java/com/baoyz/widget/SmartisanDrawable.java index f2d61b4..1c77c37 100644 --- a/library/src/main/java/com/baoyz/widget/SmartisanDrawable.java +++ b/library/src/main/java/com/baoyz/widget/SmartisanDrawable.java @@ -26,6 +26,7 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; @@ -114,7 +115,7 @@ public boolean isRunning() { } @Override - public void draw(Canvas canvas) { + public void onDraw(Canvas canvas) { canvas.save(); diff --git a/library/src/main/java/com/baoyz/widget/WaterDropDrawable.java b/library/src/main/java/com/baoyz/widget/WaterDropDrawable.java index e1d9203..462bd16 100644 --- a/library/src/main/java/com/baoyz/widget/WaterDropDrawable.java +++ b/library/src/main/java/com/baoyz/widget/WaterDropDrawable.java @@ -53,7 +53,7 @@ public WaterDropDrawable(Context context, PullRefreshLayout layout) { } @Override - public void draw(Canvas canvas) { + public void onDraw(Canvas canvas) { canvas.save(); canvas.translate(0, mTop > 0 ? mTop : 0); diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ScrollViewActivity.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ScrollViewActivity.java index 7ecab6d..1a373e0 100644 --- a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ScrollViewActivity.java +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ScrollViewActivity.java @@ -26,7 +26,7 @@ public void onRefresh() { public void run() { layout.setRefreshing(false); } - }, 3000); + }, 10000); } }); layout.setColorSchemeColors(Color.GRAY); From feba0f9f6626910f9a6d21b84cf06e61ade42600 Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Wed, 23 Sep 2015 20:23:46 +0800 Subject: [PATCH 02/11] delete unless code --- .../src/main/java/com/baoyz/widget/ArcDrawable.java | 2 +- .../main/java/com/baoyz/widget/CirclesDrawable.java | 2 +- .../main/java/com/baoyz/widget/MaterialDrawable.java | 2 +- .../main/java/com/baoyz/widget/RefreshDrawable.java | 11 ++--------- .../src/main/java/com/baoyz/widget/RingDrawable.java | 2 +- .../main/java/com/baoyz/widget/SmartisanDrawable.java | 2 +- .../main/java/com/baoyz/widget/WaterDropDrawable.java | 2 +- 7 files changed, 8 insertions(+), 15 deletions(-) diff --git a/library/src/main/java/com/baoyz/widget/ArcDrawable.java b/library/src/main/java/com/baoyz/widget/ArcDrawable.java index 9d2e2e0..90e7628 100644 --- a/library/src/main/java/com/baoyz/widget/ArcDrawable.java +++ b/library/src/main/java/com/baoyz/widget/ArcDrawable.java @@ -32,7 +32,7 @@ class ArcDrawable extends RefreshDrawable{ private int mLevel; ArcDrawable(Context context, PullRefreshLayout layout) { - super(context, layout); + super(layout); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.RED); } diff --git a/library/src/main/java/com/baoyz/widget/CirclesDrawable.java b/library/src/main/java/com/baoyz/widget/CirclesDrawable.java index 31550b5..c1ee1d3 100644 --- a/library/src/main/java/com/baoyz/widget/CirclesDrawable.java +++ b/library/src/main/java/com/baoyz/widget/CirclesDrawable.java @@ -49,7 +49,7 @@ class CirclesDrawable extends RefreshDrawable implements Runnable { private Rect mBounds; public CirclesDrawable(Context context, PullRefreshLayout layout) { - super(context, layout); + super(layout); } @Override diff --git a/library/src/main/java/com/baoyz/widget/MaterialDrawable.java b/library/src/main/java/com/baoyz/widget/MaterialDrawable.java index 742c7ed..3a38b82 100644 --- a/library/src/main/java/com/baoyz/widget/MaterialDrawable.java +++ b/library/src/main/java/com/baoyz/widget/MaterialDrawable.java @@ -151,7 +151,7 @@ class MaterialDrawable extends RefreshDrawable implements Animatable { private int mDiameter; public MaterialDrawable(Context context, PullRefreshLayout parent) { - super(context, parent); + super(parent); mParent = parent; mResources = context.getResources(); diff --git a/library/src/main/java/com/baoyz/widget/RefreshDrawable.java b/library/src/main/java/com/baoyz/widget/RefreshDrawable.java index cde0b96..baac3e6 100644 --- a/library/src/main/java/com/baoyz/widget/RefreshDrawable.java +++ b/library/src/main/java/com/baoyz/widget/RefreshDrawable.java @@ -14,10 +14,9 @@ public abstract class RefreshDrawable extends Drawable implements Drawable.Callback, Animatable { private PullRefreshLayout mRefreshLayout; - private Rect mOriginBounds; private int mDirection; - public RefreshDrawable(Context context, PullRefreshLayout layout) { + public RefreshDrawable(PullRefreshLayout layout) { mRefreshLayout = layout; } @@ -40,7 +39,7 @@ public void setDirection(int direction) { public final void draw(Canvas canvas) { int save = canvas.save(); if (mDirection == PullRefreshLayout.DIRECTION_DOWN) { - canvas.rotate(180, mOriginBounds.centerX(), mOriginBounds.centerY()); + canvas.rotate(180, getBounds().centerX(), getBounds().centerY()); } onDraw(canvas); canvas.restoreToCount(save); @@ -48,12 +47,6 @@ public final void draw(Canvas canvas) { public abstract void onDraw(Canvas canvas); - @Override - protected void onBoundsChange(Rect bounds) { - super.onBoundsChange(bounds); - mOriginBounds = bounds; - } - @Override public void invalidateDrawable(Drawable who) { final Callback callback = getCallback(); diff --git a/library/src/main/java/com/baoyz/widget/RingDrawable.java b/library/src/main/java/com/baoyz/widget/RingDrawable.java index e6b9d90..fb2fabf 100644 --- a/library/src/main/java/com/baoyz/widget/RingDrawable.java +++ b/library/src/main/java/com/baoyz/widget/RingDrawable.java @@ -29,7 +29,7 @@ class RingDrawable extends RefreshDrawable { private float mDegress; RingDrawable(Context context, PullRefreshLayout layout) { - super(context, layout); + super(layout); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(dp2px(3)); diff --git a/library/src/main/java/com/baoyz/widget/SmartisanDrawable.java b/library/src/main/java/com/baoyz/widget/SmartisanDrawable.java index 1c77c37..f4dfeb7 100644 --- a/library/src/main/java/com/baoyz/widget/SmartisanDrawable.java +++ b/library/src/main/java/com/baoyz/widget/SmartisanDrawable.java @@ -58,7 +58,7 @@ public class SmartisanDrawable extends RefreshDrawable { float mDegrees; public SmartisanDrawable(Context context, PullRefreshLayout layout) { - super(context, layout); + super(layout); mPaint.setAntiAlias(true); mPaint.setStrokeJoin(Paint.Join.ROUND); diff --git a/library/src/main/java/com/baoyz/widget/WaterDropDrawable.java b/library/src/main/java/com/baoyz/widget/WaterDropDrawable.java index 462bd16..53dbbf1 100644 --- a/library/src/main/java/com/baoyz/widget/WaterDropDrawable.java +++ b/library/src/main/java/com/baoyz/widget/WaterDropDrawable.java @@ -40,7 +40,7 @@ private enum ProgressStates { } public WaterDropDrawable(Context context, PullRefreshLayout layout) { - super(context, layout); + super(layout); mPaint = new Paint(); mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.FILL); From 6e38d5198affd3ced29b5d3d3a98d89fa6ae3536 Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Thu, 24 Sep 2015 15:48:54 +0800 Subject: [PATCH 03/11] RefreshListener support direction --- .../com/baoyz/widget/PullRefreshLayout.java | 37 ++++++++++++++++--- .../sample/ListViewActivity.java | 2 +- .../sample/RecyclerViewActivity.java | 13 ++++++- .../sample/ScrollViewActivity.java | 2 +- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java index f1d2f52..1084dc3 100644 --- a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java +++ b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java @@ -26,6 +26,8 @@ */ public class PullRefreshLayout extends ViewGroup { + private static final String TAG = "PRL"; + private static final float DECELERATE_INTERPOLATION_FACTOR = 2f; private static final int DRAG_MAX_DISTANCE = 64; private static final int INVALID_POINTER = -1; @@ -385,7 +387,7 @@ private float getMotionEventY(MotionEvent ev, int activePointerId) { return MotionEventCompat.getY(ev, index); } - private boolean canChildScroll(){ + private boolean canChildScroll() { return mScrollDirection == DIRECTION_UP ? canChildScrollUp() : canChildScrollDown(); } @@ -415,6 +417,7 @@ private boolean canChildScrollDown() { return mTarget.getScrollY() > 0; } } else { + Log.d(TAG, "getScrollY " + mTarget.getScrollY()); return ViewCompat.canScrollVertically(mTarget, DIRECTION_DOWN); } } @@ -468,7 +471,7 @@ private void moveToStart(float interpolatedTime) { mRefreshDrawable.setPercent(mDragPercent * (1 - interpolatedTime)); } - private int getTargetTop(){ + private int getTargetTop() { return mScrollDirection == DIRECTION_UP ? mTarget.getTop() : -mTarget.getTop(); // return mTarget.getTop(); } @@ -509,7 +512,7 @@ public void onAnimationEnd(Animation animation) { mRefreshDrawable.start(); if (mNotify) { if (mListener != null) { - mListener.onRefresh(); + mListener.onRefresh(mScrollDirection); } } } else { @@ -557,6 +560,10 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { mRefreshView.layout(left, top, left + width - right, top + height - bottom); } + public int getScrollDirection() { + return mScrollDirection; + } + private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getContext().getResources().getDisplayMetrics()); } @@ -565,7 +572,27 @@ public void setOnRefreshListener(OnRefreshListener listener) { mListener = listener; } - public static interface OnRefreshListener { - public void onRefresh(); + public interface OnRefreshListener { + void onRefresh(int direction); + } + + public static class SimpleOnRefreshListener implements OnRefreshListener { + + @Override + public void onRefresh(int direction) { + if (direction == DIRECTION_UP) { + onRefresh(); + } else { + onRefreshMore(); + } + } + + public void onRefresh() { + + } + + public void onRefreshMore() { + + } } } diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ListViewActivity.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ListViewActivity.java index 06db9f1..c405ca1 100644 --- a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ListViewActivity.java +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ListViewActivity.java @@ -34,7 +34,7 @@ protected void onCreate(Bundle savedInstanceState) { layout = (PullRefreshLayout) findViewById(R.id.swipeRefreshLayout); layout.setOnRefreshListener(new PullRefreshLayout.OnRefreshListener() { @Override - public void onRefresh() { + public void onRefresh(int direction) { layout.postDelayed(new Runnable() { @Override public void run() { diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/RecyclerViewActivity.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/RecyclerViewActivity.java index af928fa..0eed9e8 100644 --- a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/RecyclerViewActivity.java +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/RecyclerViewActivity.java @@ -5,6 +5,7 @@ import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -23,7 +24,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recycler_view); - RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); + final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); String[] array = new String[50]; for (int i = 0; i < array.length; i++) { @@ -34,7 +35,7 @@ protected void onCreate(Bundle savedInstanceState) { layout = (PullRefreshLayout) findViewById(R.id.swipeRefreshLayout); layout.setOnRefreshListener(new PullRefreshLayout.OnRefreshListener() { @Override - public void onRefresh() { + public void onRefresh(int direction) { layout.postDelayed(new Runnable() { @Override public void run() { @@ -43,6 +44,14 @@ public void run() { }, 4000); } }); + + recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + Log.d("byz", "getScrollY " + recyclerView.get()); + } + }); } static class ArrayAdapter extends RecyclerView.Adapter{ diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ScrollViewActivity.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ScrollViewActivity.java index 1a373e0..c1e7560 100644 --- a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ScrollViewActivity.java +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/ScrollViewActivity.java @@ -20,7 +20,7 @@ protected void onCreate(Bundle savedInstanceState) { layout = (PullRefreshLayout) findViewById(R.id.swipeRefreshLayout); layout.setOnRefreshListener(new PullRefreshLayout.OnRefreshListener() { @Override - public void onRefresh() { + public void onRefresh(int direction) { layout.postDelayed(new Runnable() { @Override public void run() { From aba205ee2db178f6fd8f15af1d3df7a43a2960a7 Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Thu, 24 Sep 2015 21:56:22 +0800 Subject: [PATCH 04/11] delete unless code --- library/src/main/java/com/baoyz/widget/PullRefreshLayout.java | 1 - 1 file changed, 1 deletion(-) diff --git a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java index f1d2f52..7ad7baf 100644 --- a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java +++ b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java @@ -6,7 +6,6 @@ import android.support.v4.view.MotionEventCompat; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; -import android.util.Log; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; From 199e4bed18bbbab3023e6ad417794c8799828fb2 Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Thu, 24 Sep 2015 21:58:02 +0800 Subject: [PATCH 05/11] add refreshDirection attribute in xml --- library/src/main/res/values/attrs.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index e733af8..6c60d01 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -8,7 +8,12 @@ - - + + + + + + + \ No newline at end of file From b4fe81cb5e3c7b564b48ae5e68ca6343c659966d Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Fri, 9 Oct 2015 12:00:35 +0800 Subject: [PATCH 06/11] support of RecylerView but only LinearLayoutManager --- build.gradle | 7 ++----- library/build.gradle | 1 + .../java/com/baoyz/widget/PullRefreshLayout.java | 13 ++++++++++++- .../sample/RecyclerViewActivity.java | 7 ------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 7efab93..186650d 100644 --- a/build.gradle +++ b/build.gradle @@ -3,15 +3,12 @@ buildscript { repositories { jcenter() - maven { - url "https://jcenter.bintray.com" - } } dependencies { classpath 'com.android.tools.build:gradle:1.3.0' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0' - classpath 'com.github.dcendents:android-maven-plugin:1.2' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.1' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/library/build.gradle b/library/build.gradle index 154cd90..a39dd92 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -23,6 +23,7 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:21.0.0' compile 'com.android.support:support-annotations:21.0.3' + compile 'com.android.support:recyclerview-v7:21.0.0' } apply plugin: 'com.github.dcendents.android-maven' diff --git a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java index 136d77e..87b60b4 100644 --- a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java +++ b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java @@ -5,7 +5,10 @@ import android.graphics.Color; import android.support.v4.view.MotionEventCompat; import android.support.v4.view.ViewCompat; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; +import android.util.Log; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; @@ -416,7 +419,15 @@ private boolean canChildScrollDown() { return mTarget.getScrollY() > 0; } } else { - Log.d(TAG, "getScrollY " + mTarget.getScrollY()); + if (mTarget instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) mTarget; + if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) { + LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); + return layoutManager.getItemCount() > 0 + && (layoutManager.findLastVisibleItemPosition() < (layoutManager.getItemCount() - 1) || layoutManager.getChildAt(layoutManager.getChildCount() - 1) + .getBottom() < layoutManager.getPaddingBottom()); + } + } return ViewCompat.canScrollVertically(mTarget, DIRECTION_DOWN); } } diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/RecyclerViewActivity.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/RecyclerViewActivity.java index 0eed9e8..7d87b10 100644 --- a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/RecyclerViewActivity.java +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/RecyclerViewActivity.java @@ -45,13 +45,6 @@ public void run() { } }); - recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - Log.d("byz", "getScrollY " + recyclerView.get()); - } - }); } static class ArrayAdapter extends RecyclerView.Adapter{ From b3dbaf1a656cce758edd11f4891f0d51828600ef Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Sun, 18 Oct 2015 16:53:21 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E4=BC=98=E5=8C=96MaterialDrawable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/baoyz/widget/MaterialDrawable.java | 29 ++++++++++--------- .../com/baoyz/widget/PullRefreshLayout.java | 1 - 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/library/src/main/java/com/baoyz/widget/MaterialDrawable.java b/library/src/main/java/com/baoyz/widget/MaterialDrawable.java index 3a38b82..e95964c 100644 --- a/library/src/main/java/com/baoyz/widget/MaterialDrawable.java +++ b/library/src/main/java/com/baoyz/widget/MaterialDrawable.java @@ -36,7 +36,6 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.util.DisplayMetrics; -import android.util.Log; import android.util.TypedValue; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; @@ -59,6 +58,7 @@ class MaterialDrawable extends RefreshDrawable implements Animatable { private static final Interpolator END_CURVE_INTERPOLATOR = new EndCurveInterpolator(); private static final Interpolator START_CURVE_INTERPOLATOR = new StartCurveInterpolator(); private static final Interpolator EASE_INTERPOLATOR = new AccelerateDecelerateInterpolator(); + private Rect mRect; @Retention(RetentionPolicy.CLASS) @IntDef({LARGE, DEFAULT}) @@ -205,8 +205,8 @@ public OvalShadow(int shadowRadius, int circleDiameter) { @Override public void draw(Canvas canvas, Paint paint) { - final int x = MaterialDrawable.this.getBounds().centerX(); - final int y = MaterialDrawable.this.getBounds().centerY(); + final int x = mRect.centerX(); + final int y = mRect.centerY(); canvas.drawCircle(x, y, (mCircleDiameter / 2 + mShadowRadius), mShadowPaint); canvas.drawCircle(x, y, (mCircleDiameter / 2), paint); @@ -287,13 +287,12 @@ public void setBackgroundColor(int color) { public void setPercent(float percent) { if (percent < .4f) return; - percent = (percent - .4f) / .6f; + percent = (percent - .4f) / .6f * 1.2f; setAlpha((int) (MAX_ALPHA * percent)); showArrow(true); - float strokeStart = ((percent) * .8f); - setStartEndTrim(0f, Math.min(MAX_PROGRESS_ANGLE, strokeStart)); + setStartEndTrim(0f, Math.min(MAX_PROGRESS_ANGLE, percent)); setArrowScale(Math.min(1f, percent)); - float rotation = percent < .8f ? 0 : (percent - .8f) / .2f * .25f; + float rotation = percent > MAX_PROGRESS_ANGLE ? (percent - MAX_PROGRESS_ANGLE) * .9f : 0; setProgressRotation(rotation); } @@ -327,7 +326,7 @@ public void offsetTopAndBottom(int offset) { @Override public void onDraw(Canvas c) { - Rect bounds = getBounds(); + Rect bounds = mRect; final int saveCount = c.save(); c.translate(0, mTop); mCircle.draw(c); @@ -340,14 +339,16 @@ public void onDraw(Canvas c) { @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); - + int w = bounds.width(); + int top = bounds.top; + mRect = new Rect(w / 2 - mDiameter / 2, top, w / 2 + mDiameter / 2, mDiameter + top); } - @Override - public void setBounds(int left, int top, int right, int bottom) { - int w = right - left; - super.setBounds(w / 2 - mDiameter / 2, top, w / 2 + mDiameter / 2, mDiameter + top); - } +// @Override +// public void setBounds(int left, int top, int right, int bottom) { +// int w = right - left; +// super.setBounds(w / 2 - mDiameter / 2, top, w / 2 + mDiameter / 2, mDiameter + top); +// } private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getContext().getResources().getDisplayMetrics()); diff --git a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java index 87b60b4..ed9106e 100644 --- a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java +++ b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java @@ -8,7 +8,6 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; -import android.util.Log; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; From 54fd49a19d6c337f0ca86afeb86a394c180589d2 Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Mon, 19 Oct 2015 01:37:34 +0800 Subject: [PATCH 08/11] fixed MaterialDrawable stop not work --- .../com/baoyz/widget/MaterialDrawable.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/library/src/main/java/com/baoyz/widget/MaterialDrawable.java b/library/src/main/java/com/baoyz/widget/MaterialDrawable.java index e95964c..b979637 100644 --- a/library/src/main/java/com/baoyz/widget/MaterialDrawable.java +++ b/library/src/main/java/com/baoyz/widget/MaterialDrawable.java @@ -36,6 +36,7 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.util.DisplayMetrics; +import android.util.Log; import android.util.TypedValue; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; @@ -59,6 +60,7 @@ class MaterialDrawable extends RefreshDrawable implements Animatable { private static final Interpolator START_CURVE_INTERPOLATOR = new StartCurveInterpolator(); private static final Interpolator EASE_INTERPOLATOR = new AccelerateDecelerateInterpolator(); private Rect mRect; + private boolean isRunning; @Retention(RetentionPolicy.CLASS) @IntDef({LARGE, DEFAULT}) @@ -386,19 +388,12 @@ public int getOpacity() { @Override public boolean isRunning() { - final ArrayList animators = mAnimators; - final int N = animators.size(); - for (int i = 0; i < N; i++) { - final Animation animator = animators.get(i); - if (animator.hasStarted() && !animator.hasEnded()) { - return true; - } - } - return false; + return isRunning; } @Override public void start() { + isRunning = true; mAnimation.reset(); mRing.storeOriginals(); // Already showing some part of the ring @@ -418,6 +413,7 @@ public void stop() { mRing.setShowArrow(false); mRing.setColorIndex(0); mRing.resetOriginals(); + isRunning = false; } private void setupAnimators() { @@ -426,6 +422,10 @@ private void setupAnimators() { public void applyTransformation(float interpolatedTime, Transformation t) { // shrink back down and complete a full rotation before starting other circles // Rotation goes between [0..1]. + if (!isRunning) { + mParent.clearAnimation(); + return; + } float targetRotation = (float) (Math.floor(ring.getStartingRotation() / MAX_PROGRESS_ARC) + 1f); final float startTrim = ring.getStartingStartTrim() @@ -463,6 +463,10 @@ public void onAnimationRepeat(Animation animation) { public void applyTransformation(float interpolatedTime, Transformation t) { // The minProgressArc is calculated from 0 to create an angle that // matches the stroke width. + if (!isRunning) { + mParent.clearAnimation(); + return; + } final float minProgressArc = (float) Math.toRadians(ring.getStrokeWidth() / (2 * Math.PI * ring.getCenterRadius())); final float startingEndTrim = ring.getStartingEndTrim(); From 0fb74e3724298d14e78ea0f82173a03766a182d2 Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Mon, 19 Oct 2015 01:38:29 +0800 Subject: [PATCH 09/11] setRefreshing default direction is up --- .../src/main/java/com/baoyz/widget/PullRefreshLayout.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java index ed9106e..3e639bc 100644 --- a/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java +++ b/library/src/main/java/com/baoyz/widget/PullRefreshLayout.java @@ -8,6 +8,7 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; +import android.util.Log; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; @@ -42,6 +43,7 @@ public class PullRefreshLayout extends ViewGroup { public static final int DIRECTION_UP = -1; public static final int DIRECTION_DOWN = 1; + public static final int DIRECTION_NONE = 0; private View mTarget; private ImageView mRefreshView; @@ -487,6 +489,9 @@ private int getTargetTop() { public void setRefreshing(boolean refreshing) { if (mRefreshing != refreshing) { + if (mScrollDirection == DIRECTION_NONE) { + mScrollDirection = DIRECTION_UP; + } setRefreshing(refreshing, false /* notify */); } } From 981acdf10e5867961748a25697051e63cdba5eda Mon Sep 17 00:00:00 2001 From: baoyongzhang Date: Mon, 19 Oct 2015 01:38:54 +0800 Subject: [PATCH 10/11] add Gank.io Demo --- sample/build.gradle | 6 +- sample/src/main/AndroidManifest.xml | 14 ++- .../sample/DemoActivity.java | 7 +- .../sample/gank/GankActivity.java | 97 +++++++++++++++++ .../sample/gank/adapter/GankAdapter.java | 103 ++++++++++++++++++ .../sample/gank/model/GankData.java | 52 +++++++++ .../sample/gank/model/GankItem.java | 50 +++++++++ .../sample/gank/network/GankApi.java | 42 +++++++ sample/src/main/res/layout/activity_demo.xml | 6 + sample/src/main/res/layout/activity_gank.xml | 22 ++++ sample/src/main/res/layout/item_feed.xml | 17 +++ sample/src/main/res/menu/menu_gank.xml | 8 ++ sample/src/main/res/values/strings.xml | 4 + 13 files changed, 422 insertions(+), 6 deletions(-) create mode 100644 sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/GankActivity.java create mode 100644 sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/adapter/GankAdapter.java create mode 100644 sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/model/GankData.java create mode 100644 sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/model/GankItem.java create mode 100644 sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/network/GankApi.java create mode 100644 sample/src/main/res/layout/activity_gank.xml create mode 100644 sample/src/main/res/layout/item_feed.xml create mode 100644 sample/src/main/res/menu/menu_gank.xml diff --git a/sample/build.gradle b/sample/build.gradle index c2f7056..0a47cf1 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -6,7 +6,7 @@ android { defaultConfig { applicationId "com.baoyz.pullrefreshlayout.sample" - minSdkVersion 8 + minSdkVersion 14 targetSdkVersion 21 versionCode 1 versionName "1.0" @@ -23,5 +23,9 @@ dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:support-v4:21.0.0' compile 'com.android.support:recyclerview-v7:21.0.0' + compile 'com.android.support:cardview-v7:21.0.0' compile project(':library') + compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' + compile 'com.squareup.retrofit:converter-moshi:2.0.0-beta2' + compile 'com.squareup.picasso:picasso:2.5.2' } diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 17ce1df..2f6971b 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -2,13 +2,15 @@ + + @@ -16,9 +18,13 @@ - - - + + + + + diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/DemoActivity.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/DemoActivity.java index 223a8d1..678f523 100644 --- a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/DemoActivity.java +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/DemoActivity.java @@ -5,7 +5,7 @@ import android.os.Bundle; import android.view.View; -import com.baoyz.widget.PullRefreshLayout; +import com.baoyz.pullrefreshlayout.sample.gank.GankActivity; public class DemoActivity extends Activity { @@ -29,4 +29,9 @@ public void onScrollViewClick(View view) { startActivity(new Intent(this, ScrollViewActivity.class)); } + public void onGankDemoClick(View view) { + // Content from http://gank.io + startActivity(new Intent(this, GankActivity.class)); + } + } diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/GankActivity.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/GankActivity.java new file mode 100644 index 0000000..f6c795b --- /dev/null +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/GankActivity.java @@ -0,0 +1,97 @@ +package com.baoyz.pullrefreshlayout.sample.gank; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.widget.Toast; + +import com.baoyz.pullrefreshlayout.sample.R; +import com.baoyz.pullrefreshlayout.sample.gank.adapter.GankAdapter; +import com.baoyz.pullrefreshlayout.sample.gank.model.GankData; +import com.baoyz.pullrefreshlayout.sample.gank.network.GankApi; +import com.baoyz.widget.PullRefreshLayout; + +import retrofit.Call; +import retrofit.Callback; +import retrofit.MoshiConverterFactory; +import retrofit.Response; +import retrofit.Retrofit; + +/** + * Content from http://gank.io + */ +public class GankActivity extends Activity { + + private RecyclerView mRecyclerView; + private GankApi mGankApi; + private PullRefreshLayout mRefreshLayout; + private int mCurrentPage = 1; + private GankAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_gank); + + mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView); + mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + mAdapter = new GankAdapter(); + mRecyclerView.setAdapter(mAdapter); + + mRefreshLayout = (PullRefreshLayout) findViewById(R.id.refreshLayout); + mRefreshLayout.setRefreshStyle(PullRefreshLayout.STYLE_SMARTISAN); + mRefreshLayout.setOnRefreshListener(new PullRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh(int direction) { + switch (direction) { + case PullRefreshLayout.DIRECTION_UP: + loadData(1); + break; + case PullRefreshLayout.DIRECTION_DOWN: + loadData(mCurrentPage + 1); + break; + } + } + }); + + mGankApi = new Retrofit + .Builder() + .baseUrl(GankApi.BASE_URL) + .addConverterFactory(MoshiConverterFactory.create()) + .build() + .create(GankApi.class); + + mRefreshLayout.setRefreshing(true); + loadData(mCurrentPage); + } + + private void loadData(final int page) { + Call call = mGankApi.getData(page); + call.enqueue(new Callback() { + @Override + public void onResponse(Response response, Retrofit retrofit) { + mRefreshLayout.setRefreshing(false); + if (!response.isSuccess()) { + Toast.makeText(GankActivity.this, response.code() + ", " + response.message(), Toast.LENGTH_SHORT).show(); + return; + } + mCurrentPage = page; + if (mCurrentPage == 1) { + mAdapter.clear(); + } + GankData data = response.body(); + if (data == null || data.getResults() == null || data.getResults().size() <= 0) { + return; + } + mAdapter.addItems(data.getResults()); + mAdapter.notifyDataSetChanged(); + } + + @Override + public void onFailure(Throwable throwable) { + mRefreshLayout.setRefreshing(false); + } + }); + } +} diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/adapter/GankAdapter.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/adapter/GankAdapter.java new file mode 100644 index 0000000..23ad29f --- /dev/null +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/adapter/GankAdapter.java @@ -0,0 +1,103 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 baoyongzhang + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.baoyz.pullrefreshlayout.sample.gank.adapter; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.baoyz.pullrefreshlayout.sample.R; +import com.baoyz.pullrefreshlayout.sample.gank.model.GankItem; +import com.squareup.picasso.Picasso; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by baoyz on 15/1/14. + */ +public class GankAdapter extends RecyclerView.Adapter { + + private int mLastPosition = -1; + private final List mItems; + + public GankAdapter() { + mItems = new ArrayList<>(); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { + return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_feed, viewGroup, false)); + } + + public void addItems(List items) { + if (items == null || items.size() <= 0) + return; + mItems.addAll(items); + } + + public void clear() { + mItems.clear(); + } + + @Override + public void onBindViewHolder(GankAdapter.ViewHolder holder, int position) { + if (position > mLastPosition) { + mLastPosition = position; + startItemAnimation(holder, position); + } + GankItem item = mItems.get(position); + Picasso.with(holder.mView.getContext()).load(item.getUrl()).into(holder.mImageView); + } + + @Override + public int getItemCount() { + return mItems.size(); + } + + protected void startItemAnimation(final GankAdapter.ViewHolder holder, int position) { + holder.mView.post(new Runnable() { + @Override + public void run() { + holder.mView.setTranslationY(holder.mView.getMeasuredHeight() / 2); + holder.mView.setAlpha(0); + holder.mView.animate().translationY(0).alpha(1).setDuration(500).start(); + } + }); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + + public View mView; + public ImageView mImageView; + + public ViewHolder(View itemView) { + super(itemView); + mView = itemView; + mImageView = (ImageView) itemView.findViewById(R.id.imageView); + } + } +} diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/model/GankData.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/model/GankData.java new file mode 100644 index 0000000..e37c43a --- /dev/null +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/model/GankData.java @@ -0,0 +1,52 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 baoyongzhang + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.baoyz.pullrefreshlayout.sample.gank.model; + +import java.util.List; + +/** + * android-PullRefreshLayout + * Created by baoyz on 15/10/18. + */ +public class GankData { + + private boolean error; + private List results; + + public boolean isError() { + return error; + } + + public void setError(boolean error) { + this.error = error; + } + + public List getResults() { + return results; + } + + public void setResults(List results) { + this.results = results; + } +} diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/model/GankItem.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/model/GankItem.java new file mode 100644 index 0000000..e2df6b9 --- /dev/null +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/model/GankItem.java @@ -0,0 +1,50 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 baoyongzhang + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.baoyz.pullrefreshlayout.sample.gank.model; + +/** + * android-PullRefreshLayout + * Created by baoyz on 15/10/18. + */ +public class GankItem { + + private String url; + private String desc; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/network/GankApi.java b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/network/GankApi.java new file mode 100644 index 0000000..6dd6f82 --- /dev/null +++ b/sample/src/main/java/com/baoyz/pullrefreshlayout/sample/gank/network/GankApi.java @@ -0,0 +1,42 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 baoyongzhang + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.baoyz.pullrefreshlayout.sample.gank.network; + +import com.baoyz.pullrefreshlayout.sample.gank.model.GankData; + +import retrofit.Call; +import retrofit.http.GET; +import retrofit.http.Path; + +/** + * android-PullRefreshLayout + * Created by baoyz on 15/10/18. + */ +public interface GankApi { + + String BASE_URL = "http://gank.avosapps.com"; + + @GET("/api/data/福利/10/{page}") + Call getData(@Path("page")int page); +} diff --git a/sample/src/main/res/layout/activity_demo.xml b/sample/src/main/res/layout/activity_demo.xml index 78c03f3..7ca438b 100644 --- a/sample/src/main/res/layout/activity_demo.xml +++ b/sample/src/main/res/layout/activity_demo.xml @@ -24,4 +24,10 @@ android:onClick="onScrollViewClick" android:text="ScrollView"/> +