22 | * 自定义流程 23 | * 1、只需要继承 {@link IBaseLoadMoreView},实现相应的方法。 24 | * 2、全局设置,可以通过 25 | * {@link com.zinc.jrecycleview.config.JRecycleViewManager#setLoadMoreView(IBaseLoadMoreView)} 26 | * 3、单个设置,可以通过 27 | * {@link com.zinc.jrecycleview.adapter.JRefreshAndLoadMoreAdapter#setLoadMoreView(IBaseLoadMoreView)} 28 | *
29 | * version : 1.0.0 30 | */ 31 | 32 | public class OrdinaryLoadMoreView extends IBaseLoadMoreView { 33 | 34 | private View mLoadMoreView; 35 | private BallSpinFadeLoader mProgressBar; 36 | private TextView mTvTip; 37 | private ImageView mIvReload; 38 | 39 | public OrdinaryLoadMoreView(Context context) { 40 | this(context, null, 0); 41 | } 42 | 43 | public OrdinaryLoadMoreView(Context context, 44 | @Nullable AttributeSet attrs) { 45 | this(context, attrs, 0); 46 | } 47 | 48 | public OrdinaryLoadMoreView(Context context, 49 | @Nullable AttributeSet attrs, 50 | int defStyleAttr) { 51 | super(context, attrs, defStyleAttr); 52 | } 53 | 54 | @Override 55 | protected View getLoadView() { 56 | return this.mLoadMoreView; 57 | } 58 | 59 | @Override 60 | protected void onNoMore() { 61 | this.mProgressBar.setVisibility(GONE); 62 | this.mTvTip.setText(getContext().getString(R.string.j_recycle_no_more)); 63 | this.mTvTip.setVisibility(VISIBLE); 64 | this.mIvReload.setVisibility(GONE); 65 | } 66 | 67 | @Override 68 | protected void onError() { 69 | this.mProgressBar.setVisibility(GONE); 70 | this.mTvTip.setText(getContext().getString(R.string.j_recycle_reload)); 71 | this.mTvTip.setVisibility(VISIBLE); 72 | this.mIvReload.setVisibility(VISIBLE); 73 | } 74 | 75 | @Override 76 | protected void onPullToAction() { 77 | this.mProgressBar.setVisibility(GONE); 78 | this.mTvTip.setText(getContext().getString(R.string.j_recycle_pull_to_load)); 79 | this.mTvTip.setVisibility(VISIBLE); 80 | this.mIvReload.setVisibility(GONE); 81 | } 82 | 83 | @Override 84 | protected void onReleaseToAction() { 85 | this.mProgressBar.setVisibility(GONE); 86 | this.mTvTip.setText(getContext().getString(R.string.j_recycle_release_to_load)); 87 | this.mTvTip.setVisibility(VISIBLE); 88 | this.mIvReload.setVisibility(GONE); 89 | } 90 | 91 | @Override 92 | protected void onExecuting() { 93 | this.mProgressBar.setVisibility(VISIBLE); 94 | this.mTvTip.setText(getContext().getString(R.string.j_recycle_loading)); 95 | this.mTvTip.setVisibility(VISIBLE); 96 | this.mIvReload.setVisibility(GONE); 97 | } 98 | 99 | @Override 100 | protected void onDone() { 101 | this.mProgressBar.setVisibility(GONE); 102 | this.mTvTip.setText(getContext().getString(R.string.j_recycle_loaded)); 103 | this.mTvTip.setVisibility(VISIBLE); 104 | this.mIvReload.setVisibility(GONE); 105 | } 106 | 107 | @Override 108 | protected View initView(Context context) { 109 | this.mLoadMoreView = LayoutInflater.from(context) 110 | .inflate(R.layout.j_widget_ordinary_load_more_view, 111 | this, 112 | false); 113 | this.mProgressBar = this.mLoadMoreView.findViewById(R.id.ball_loader); 114 | this.mTvTip = this.mLoadMoreView.findViewById(R.id.tv_tip); 115 | this.mIvReload = this.mLoadMoreView.findViewById(R.id.iv_reload); 116 | 117 | return this.mLoadMoreView; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /lib.recycleview/src/main/java/com/zinc/jrecycleview/loadview/OrdinaryRefreshLoadView.java: -------------------------------------------------------------------------------- 1 | package com.zinc.jrecycleview.loadview; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.animation.Animation; 8 | import android.view.animation.RotateAnimation; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import androidx.annotation.Nullable; 13 | 14 | import com.zinc.jrecycleview.loadview.base.IBaseRefreshLoadView; 15 | import com.zinc.jrecycleview.loadview.bean.MoveInfo; 16 | import com.zinc.jrecycleview.utils.LogUtils; 17 | import com.zinc.jrecycleview.widget.BallSpinFadeLoader; 18 | import com.zinc.librecycleview.R; 19 | 20 | /** 21 | * author : Jiang Pengyong 22 | * time : 2018-03-17 14:35 23 | * email : 56002982@qq.com 24 | * desc : 最为普通的下拉刷新头部 25 | *
26 | * 自定义流程 27 | * 1、只需要继承 {@link IBaseRefreshLoadView},实现相应的方法。 28 | * 2、全局设置,可以通过 29 | * {@link com.zinc.jrecycleview.config.JRecycleViewManager#setRefreshLoadView(IBaseRefreshLoadView)} 30 | * 3、单个设置,可以通过 31 | * {@link com.zinc.jrecycleview.adapter.JRefreshAndLoadMoreAdapter#setRefreshLoadView(IBaseRefreshLoadView)} 32 | *
33 | * version : 1.0.0
34 | */
35 |
36 | public class OrdinaryRefreshLoadView extends IBaseRefreshLoadView {
37 |
38 | private View mLoadView;
39 |
40 | // 动画时长
41 | private static final int ANIM_DURATION = 180;
42 |
43 | //视图控件
44 | private TextView mTvRefreshStatus;
45 | private ImageView mIvArrow;
46 | private BallSpinFadeLoader mBallLoader;
47 |
48 | //向上转动画
49 | private RotateAnimation mArrowToUpAnim;
50 | //向下转动画
51 | private RotateAnimation mArrowToDownAnim;
52 |
53 | public OrdinaryRefreshLoadView(Context context) {
54 | this(context, null, 0);
55 | }
56 |
57 | public OrdinaryRefreshLoadView(Context context,
58 | @Nullable AttributeSet attrs) {
59 | this(context, attrs, 0);
60 | }
61 |
62 | public OrdinaryRefreshLoadView(Context context,
63 | @Nullable AttributeSet attrs,
64 | int defStyleAttr) {
65 | super(context, attrs, defStyleAttr);
66 | }
67 |
68 | @Override
69 | protected void onMoving(MoveInfo moveInfo) {
70 | LogUtils.i(TAG, "onMoving: " + moveInfo.toString());
71 | }
72 |
73 | @Override
74 | protected View getLoadView() {
75 | return mLoadView;
76 | }
77 |
78 | @Override
79 | protected View initView(Context context) {
80 | mLoadView = LayoutInflater
81 | .from(context)
82 | .inflate(R.layout.j_widget_ordinary_load_refresh_view, this, false);
83 |
84 | mTvRefreshStatus = mLoadView.findViewById(R.id.tv_refresh_status);
85 | mIvArrow = mLoadView.findViewById(R.id.iv_arrow);
86 | mBallLoader = mLoadView.findViewById(R.id.ball_loader);
87 |
88 | //向上转,从0->180
89 | mArrowToUpAnim = new RotateAnimation(0, 180,
90 | Animation.RELATIVE_TO_SELF, 0.5f,
91 | Animation.RELATIVE_TO_SELF, 0.5f);
92 | //动画时长
93 | mArrowToUpAnim.setDuration(ANIM_DURATION);
94 | //让动画停留在最后一帧
95 | mArrowToUpAnim.setFillAfter(true);
96 |
97 | //向下转,从180->0
98 | mArrowToDownAnim = new RotateAnimation(180, 0,
99 | Animation.RELATIVE_TO_SELF, 0.5f,
100 | Animation.RELATIVE_TO_SELF, 0.5f);
101 | mArrowToDownAnim.setDuration(ANIM_DURATION);
102 | mArrowToDownAnim.setFillAfter(true);
103 |
104 | return mLoadView;
105 | }
106 |
107 | @Override
108 | protected void onPullToAction() {
109 | mBallLoader.setVisibility(GONE);
110 | mIvArrow.setVisibility(VISIBLE);
111 | mTvRefreshStatus.setText(getContext().getString(R.string.j_recycle_pull_to_refresh));
112 |
113 | if (mCurState == STATE_RELEASE_TO_ACTION) {//释放刷新->下拉刷新:把箭头往回转
114 | mIvArrow.startAnimation(mArrowToDownAnim);
115 | } else if (mCurState == STATE_EXECUTING) {//刷新ing->下拉刷新
116 | mIvArrow.clearAnimation();
117 | }
118 | }
119 |
120 | @Override
121 | protected void onReleaseToAction() {
122 | mBallLoader.setVisibility(GONE);
123 | mIvArrow.setVisibility(VISIBLE);
124 | mTvRefreshStatus.setText(getContext().getString(R.string.j_recycle_release_to_refresh));
125 | //需要先清空动画
126 | mIvArrow.clearAnimation();
127 | mIvArrow.startAnimation(mArrowToUpAnim);
128 | }
129 |
130 | @Override
131 | protected void onExecuting() {
132 | mBallLoader.setVisibility(VISIBLE);
133 |
134 | //需要先清空箭头状态,后在进行视图隐藏,否则会有问题
135 | mIvArrow.clearAnimation();
136 | mIvArrow.setVisibility(GONE);
137 |
138 | mTvRefreshStatus.setText(getContext().getString(R.string.j_recycle_refreshing));
139 | }
140 |
141 | @Override
142 | protected void onDone() {
143 | mIvArrow.clearAnimation();
144 | mIvArrow.setVisibility(GONE);
145 | mBallLoader.setVisibility(GONE);
146 | mTvRefreshStatus.setText(getContext().getString(R.string.j_recycle_refreshed));
147 | }
148 |
149 | }
150 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/loadview/base/IBaseLoadMoreView.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.loadview.base;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 |
7 | import androidx.annotation.Nullable;
8 |
9 | import com.zinc.jrecycleview.adapter.JRefreshAndLoadMoreAdapter;
10 | import com.zinc.jrecycleview.utils.LogUtils;
11 |
12 | /**
13 | * author : Jiang Pengyong
14 | * time : 2018-03-19 12:34
15 | * email : 56002982@qq.com
16 | * desc : 加载更多,抽象类
17 | * version : 1.0.0
18 | */
19 |
20 | public abstract class IBaseLoadMoreView extends IBaseWrapperView {
21 |
22 | protected JRefreshAndLoadMoreAdapter.OnLoadMoreListener mOnLoadMoreListener;
23 |
24 | public IBaseLoadMoreView(Context context) {
25 | super(context);
26 | }
27 |
28 | public IBaseLoadMoreView(Context context,
29 | @Nullable AttributeSet attrs) {
30 | super(context, attrs);
31 | }
32 |
33 | public IBaseLoadMoreView(Context context,
34 | @Nullable AttributeSet attrs,
35 | int defStyleAttr) {
36 | super(context, attrs, defStyleAttr);
37 | }
38 |
39 | @Override
40 | protected void wrapper(Context context, View view) {
41 |
42 | addView(view);
43 |
44 | measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
45 | this.mHeight = getMeasuredHeight();
46 | }
47 |
48 | public void setOnLoadMoreListener(JRefreshAndLoadMoreAdapter.OnLoadMoreListener listener) {
49 | this.mOnLoadMoreListener = listener;
50 | }
51 |
52 | public JRefreshAndLoadMoreAdapter.OnLoadMoreListener getOnLoadMoreListener() {
53 | return mOnLoadMoreListener;
54 | }
55 |
56 | /**
57 | * 释放动作,会进入两种状态:1、等待刷新;2、正在刷新;
58 | *
59 | * @param visible 可见高度
60 | * @return 返回是否正在刷新
61 | */
62 | public boolean releaseAction(int visible) {
63 | //是否正在刷新
64 | boolean isOnRefresh = false;
65 |
66 | LogUtils.i(TAG, "visible: " + visible + "; height: " + mHeight);
67 |
68 | //如果释放的时候,大于刷新视图的高度值且未进入刷新状态,则需要进入刷新状态
69 | if (visible > this.mHeight && this.mCurState < STATE_EXECUTING) {
70 | setState(STATE_EXECUTING);
71 | isOnRefresh = true;
72 | }
73 |
74 | smoothScrollTo(this.mHeight);
75 |
76 | return isOnRefresh;
77 | }
78 |
79 | /**
80 | * 加载完毕
81 | */
82 | public void loadComplete() {
83 | setState(STATE_DONE);
84 | reset(mHeight);
85 | }
86 |
87 | /**
88 | * 重置
89 | */
90 | public void reset() {
91 | setState(STATE_PULL_TO_ACTION);
92 | reset(mHeight);
93 | }
94 |
95 | /**
96 | * 加载错误
97 | */
98 | public void loadError() {
99 | setState(STATE_ERROR);
100 | }
101 |
102 | /**
103 | * 没有更多
104 | */
105 | public void noMore() {
106 | setState(STATE_NO_MORE);
107 | smoothScrollTo(mHeight);
108 | }
109 |
110 | @Override
111 | protected void onOther(int state) {
112 | switch (state) {
113 | case STATE_NO_MORE:
114 | onNoMore();
115 | break;
116 | case STATE_ERROR:
117 | onError();
118 | break;
119 | }
120 | }
121 |
122 | /**
123 | * @param visibleHeight 可视高度
124 | * @param delta 垂直增量
125 | */
126 | public void onMove(int visibleHeight, float delta) {
127 | //需要符合:1、可见高度大于控件高度;2、拉动距离要大于0
128 | float viewHeight = visibleHeight + delta;
129 | if (viewHeight < mHeight) {
130 | viewHeight = mHeight;
131 | }
132 | setVisibleHeight((int) viewHeight);
133 |
134 | LogUtils.i(TAG,
135 | "visibleHeight: " + visibleHeight + "; " +
136 | "height: " + mHeight + "; " +
137 | "viewHeight: " + viewHeight);
138 |
139 | //当前状态为: 1、上拉刷新; 2、释放刷新
140 | if (this.mCurState <= STATE_RELEASE_TO_ACTION) {
141 | //小于loadView高度
142 | if (visibleHeight <= mHeight) {
143 | if (this.mCurState == STATE_ERROR) {
144 | setState(STATE_ERROR);
145 | } else {
146 | setState(STATE_PULL_TO_ACTION);
147 | }
148 | } else {
149 | setState(STATE_RELEASE_TO_ACTION);
150 | }
151 | }
152 |
153 | }
154 |
155 | /**
156 | * 没有更多状态
157 | */
158 | protected abstract void onNoMore();
159 |
160 | /**
161 | * 加载出错
162 | */
163 | protected abstract void onError();
164 |
165 | }
166 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/loadview/base/IBaseRefreshLoadView.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.loadview.base;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 |
7 | import androidx.annotation.Nullable;
8 |
9 | import com.zinc.jrecycleview.adapter.JRefreshAndLoadMoreAdapter;
10 | import com.zinc.jrecycleview.loadview.bean.MoveInfo;
11 | import com.zinc.jrecycleview.utils.LogUtils;
12 |
13 | /**
14 | * author : Jiang Pengyong
15 | * time : 2018-03-17 15:54
16 | * email : 56002982@qq.com
17 | * desc : 下拉刷新
18 | * version : 1.0.0
19 | */
20 |
21 | public abstract class IBaseRefreshLoadView extends IBaseWrapperView {
22 |
23 | private MoveInfo mMoveInfo;
24 |
25 | private JRefreshAndLoadMoreAdapter.OnRefreshListener mOnRefreshListener;
26 |
27 | public IBaseRefreshLoadView(Context context) {
28 | this(context, null, 0);
29 | }
30 |
31 | public IBaseRefreshLoadView(Context context,
32 | @Nullable AttributeSet attrs) {
33 | this(context, attrs, 0);
34 | }
35 |
36 | public IBaseRefreshLoadView(Context context,
37 | @Nullable AttributeSet attrs,
38 | int defStyleAttr) {
39 | super(context, attrs, defStyleAttr);
40 |
41 | mMoveInfo = new MoveInfo();
42 | }
43 |
44 | @Override
45 | protected void wrapper(Context context, View view) {
46 |
47 | addView(view);
48 |
49 | measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
50 | this.mHeight = getMeasuredHeight();
51 |
52 | setVisibleHeight(0);
53 | }
54 |
55 | public void setOnRefreshListener(JRefreshAndLoadMoreAdapter.OnRefreshListener listener) {
56 | this.mOnRefreshListener = listener;
57 | }
58 |
59 | public JRefreshAndLoadMoreAdapter.OnRefreshListener getOnRefreshListener() {
60 | return this.mOnRefreshListener;
61 | }
62 |
63 | /**
64 | * 释放动作,会进入两种状态:1、等待刷新;2、正在刷新;
65 | *
66 | * @param visibleHeight 可见高度
67 | * @return 是否正在刷新
68 | */
69 | public boolean releaseAction(int visibleHeight) {
70 | // 是否正在刷新
71 | boolean isOnRefresh = false;
72 | // 可见高度
73 | // int height = visibleHeight;
74 | // 此次释放后,需要进入的目标高度
75 | int destHeight = 0;
76 |
77 | // 当前已经正在刷新,则让视图回到加载视图的高度(正在刷新,不用返回true,否则会再触发)
78 | if (this.mCurState == STATE_EXECUTING) {
79 | destHeight = this.mHeight;
80 | }
81 |
82 | // 如果释放的时候,大于刷新视图的高度值且未进入刷新状态,则需要进入刷新状态
83 | if (visibleHeight > this.mHeight && this.mCurState < STATE_EXECUTING) {
84 | setState(STATE_EXECUTING);
85 | destHeight = this.mHeight;
86 | isOnRefresh = true;
87 | }
88 |
89 | smoothScrollTo(destHeight);
90 |
91 | return isOnRefresh;
92 | }
93 |
94 | /**
95 | * @param delta 垂直增量
96 | */
97 | public void onMove(int visibleHeight, int delta) {
98 |
99 | LogUtils.i(TAG, "[visibleHeight: " + visibleHeight + "; " +
100 | "delta: " + delta + "]");
101 |
102 | //需要符合:1、可见高度大于0,即用户已有向下拉动;2、拉动距离要大于0
103 | if (visibleHeight > 0 || delta > 0) {
104 | setVisibleHeight((visibleHeight + delta));
105 |
106 | //当前状态为1、下拉刷新;2、释放刷新
107 | if (mCurState <= STATE_RELEASE_TO_ACTION) {
108 |
109 | //小于loadView高度
110 | if (visibleHeight <= mHeight) {
111 | setState(STATE_PULL_TO_ACTION);
112 | } else {
113 | setState(STATE_RELEASE_TO_ACTION);
114 | }
115 |
116 | }
117 |
118 | int height;
119 | if (visibleHeight >= mHeight) {
120 | height = mHeight;
121 | } else {
122 | height = visibleHeight;
123 | }
124 |
125 | mMoveInfo.setViewHeight(mHeight);
126 | mMoveInfo.setDragHeight(visibleHeight);
127 | mMoveInfo.setPercent(height * 100 / mHeight);
128 |
129 | onMoving(mMoveInfo);
130 |
131 | }
132 | }
133 |
134 | public void refreshComplete() {
135 | setState(STATE_DONE);
136 | reset(0);
137 | }
138 |
139 | @Override
140 | protected void onOther(int state) {
141 | //目前空实现,需扩展,可子类进行重写
142 | }
143 |
144 | /**
145 | * 下拉过程中的回调,可以更加细微的处理动画
146 | *
147 | * @param moveInfo
148 | */
149 | protected abstract void onMoving(MoveInfo moveInfo);
150 |
151 | }
152 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/loadview/base/IBaseWrapperView.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.loadview.base;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.content.Context;
5 | import android.util.AttributeSet;
6 | import android.view.View;
7 | import android.widget.LinearLayout;
8 |
9 | import androidx.annotation.Nullable;
10 |
11 | import com.zinc.jrecycleview.utils.LogUtils;
12 |
13 | /**
14 | * author : Jiang Pengyong
15 | * time : 2018-04-16 14:28
16 | * email : 56002982@qq.com
17 | * desc : 上拉和下拉基类
18 | * version : 1.0.0
19 | */
20 |
21 | public abstract class IBaseWrapperView extends LinearLayout {
22 |
23 | protected String TAG = this.getClass().getSimpleName();
24 |
25 | protected final static int INDEX = 1;
26 |
27 | private static final int SCROLL_DURATION = 300;
28 |
29 | // 加载出错
30 | public final static int STATE_ERROR = INDEX;
31 | // 下拉刷新或上拉更多状态:
32 | // 1、还没操作;
33 | // 2、下拉的高度未超过显示的高度;
34 | public final static int STATE_PULL_TO_ACTION = INDEX << 1;
35 | // 释放执行
36 | public final static int STATE_RELEASE_TO_ACTION = INDEX << 2;
37 | // 执行中
38 | public final static int STATE_EXECUTING = INDEX << 3;
39 | // 执行完毕
40 | public final static int STATE_DONE = INDEX << 4;
41 | // 没有更多
42 | public final static int STATE_NO_MORE = INDEX << 5;
43 |
44 | // 当前状态
45 | protected int mCurState;
46 |
47 | // 本视图高度
48 | protected int mHeight;
49 |
50 | public IBaseWrapperView(Context context) {
51 | this(context, null, 0);
52 | }
53 |
54 | public IBaseWrapperView(Context context,
55 | @Nullable AttributeSet attrs) {
56 | this(context, attrs, 0);
57 | }
58 |
59 | public IBaseWrapperView(Context context,
60 | @Nullable AttributeSet attrs,
61 | int defStyleAttr) {
62 | super(context, attrs, defStyleAttr);
63 |
64 | init(context);
65 | }
66 |
67 | private void init(Context context) {
68 | this.mCurState = STATE_PULL_TO_ACTION;
69 |
70 | LayoutParams layoutParams =
71 | new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
72 | layoutParams.setMargins(0, 0, 0, 0);
73 | setLayoutParams(layoutParams);
74 | setPadding(0, 0, 0, 0);
75 |
76 | View view = initView(context);
77 | wrapper(context, view);
78 | }
79 |
80 | protected abstract void wrapper(Context context, View view);
81 |
82 | public int getViewHeight() {
83 | return this.mHeight;
84 | }
85 |
86 | public void setHeight(int height) {
87 | this.mHeight = height;
88 | }
89 |
90 | /**
91 | * 获取当前状态
92 | */
93 | public int getCurState() {
94 | return mCurState;
95 | }
96 |
97 | /**
98 | * 获取刷新的根视图
99 | */
100 | protected abstract View getLoadView();
101 |
102 | /**
103 | * 获取加载视图的高度
104 | */
105 | public int getVisibleHeight() {
106 | LinearLayout.LayoutParams layoutParams
107 | = (LinearLayout.LayoutParams) this.getLoadView().getLayoutParams();
108 | return layoutParams.height;
109 | }
110 |
111 | /**
112 | * 设置加载View的高度
113 | *
114 | * @param height 设置可见高度
115 | */
116 | protected void setVisibleHeight(int height) {
117 | if (height <= 0) {
118 | height = 0;
119 | }
120 | LinearLayout.LayoutParams layoutParams
121 | = (LinearLayout.LayoutParams) getLoadView().getLayoutParams();
122 | layoutParams.height = height;
123 | getLoadView().setLayoutParams(layoutParams);
124 | }
125 |
126 | /**
127 | * 设置当前状态
128 | *
129 | * @param state 当前状态
130 | */
131 | public void setState(int state) {
132 | //如果与当前状态相同,不做任何处理
133 | if (state == this.mCurState) {
134 | return;
135 | }
136 |
137 | LogUtils.i(TAG, "state: " + state);
138 |
139 | switch (state) {
140 | //下拉执行
141 | case STATE_PULL_TO_ACTION:
142 | onPullToAction();
143 | break;
144 |
145 | //释放执行
146 | case STATE_RELEASE_TO_ACTION:
147 | onReleaseToAction();
148 | break;
149 |
150 | //执行中
151 | case STATE_EXECUTING:
152 | onExecuting();
153 | break;
154 |
155 | //执行完毕
156 | case STATE_DONE:
157 | onDone();
158 | break;
159 | default:
160 | onOther(state);
161 | }
162 |
163 | //保存为当前状态
164 | this.mCurState = state;
165 | }
166 |
167 | /**
168 | * 重置状态
169 | *
170 | * @param destHeight 目标高度
171 | */
172 | protected void reset(int destHeight) {
173 | smoothScrollTo(destHeight);
174 | postDelayed(new Runnable() {
175 | @Override
176 | public void run() {
177 | setState(STATE_PULL_TO_ACTION);
178 | }
179 | }, 200);
180 | }
181 |
182 | /**
183 | * 平滑滚动至某个高度
184 | *
185 | * @param destHeight 目标高度
186 | */
187 | protected void smoothScrollTo(int destHeight) {
188 | smoothScrollTo(destHeight, SCROLL_DURATION);
189 | }
190 |
191 | /**
192 | * 平滑滚动至某个高度
193 | *
194 | * @param destHeight 目标高度
195 | * @param durTime 时长
196 | */
197 | protected void smoothScrollTo(int destHeight, int durTime) {
198 | // 设置从可见高度->目标高度
199 | ValueAnimator valueAnimator = ValueAnimator.ofInt(getVisibleHeight(), destHeight);
200 | valueAnimator.setDuration(durTime);
201 | valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
202 | @Override
203 | public void onAnimationUpdate(ValueAnimator animation) {
204 | setVisibleHeight((Integer) animation.getAnimatedValue());
205 | }
206 | });
207 | valueAnimator.start();
208 | }
209 |
210 | /**
211 | * 等待上拉 或 等待下拉的状态 视图表现
212 | */
213 | protected abstract void onPullToAction();
214 |
215 | /**
216 | * 释放执行(释放刷新 或 释放加载更多)视图表现
217 | */
218 | protected abstract void onReleaseToAction();
219 |
220 | /**
221 | * 执行中 视图表现
222 | */
223 | protected abstract void onExecuting();
224 |
225 | /**
226 | * 执行完视图表现
227 | */
228 | protected abstract void onDone();
229 |
230 | /**
231 | * 扩展方法,主要用于后面扩展一写细节的状态,
232 | * 现用于LoadMore增加{@link IBaseLoadMoreView#STATE_NO_MORE}状态
233 | *
234 | * @param state 当前状态
235 | */
236 | protected abstract void onOther(int state);
237 |
238 | /**
239 | * 初始化视图,用于加载自己的视图
240 | *
241 | * @param context 上下文
242 | * @return 视图
243 | */
244 | protected abstract View initView(Context context);
245 |
246 | }
247 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/loadview/bean/MoveInfo.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.loadview.bean;
2 |
3 | /**
4 | * author : Jiang Pengyong
5 | * time : 2018-04-17 16:07
6 | * email : 56002982@qq.com
7 | * desc : 移动信息
8 | * version : 1.0.0
9 | */
10 |
11 | public class MoveInfo {
12 |
13 | // 视图的高度
14 | private int viewHeight;
15 | // 下拉高度
16 | private int dragHeight;
17 | // 百分比(最大100,最小0)
18 | private int percent;
19 |
20 | public MoveInfo() {
21 | }
22 |
23 | public int getViewHeight() {
24 | return viewHeight;
25 | }
26 |
27 | public void setViewHeight(int viewHeight) {
28 | this.viewHeight = viewHeight;
29 | }
30 |
31 | public int getDragHeight() {
32 | return dragHeight;
33 | }
34 |
35 | public void setDragHeight(int dragHeight) {
36 | this.dragHeight = dragHeight;
37 | }
38 |
39 | public int getPercent() {
40 | return percent;
41 | }
42 |
43 | public void setPercent(int percent) {
44 | this.percent = percent;
45 | }
46 |
47 | @Override
48 | public String toString() {
49 | return "MoveInfo{" +
50 | "viewHeight=" + viewHeight +
51 | ", dragHeight=" + dragHeight +
52 | ", percent=" + percent +
53 | '}';
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/stick/IStick.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.stick;
2 |
3 | /**
4 | * author : Jiang Pengyong
5 | * time : 2019-07-26 17:09
6 | * desc : 粘性接口
7 | * version : 1.0.0
8 | */
9 | public interface IStick {
10 | }
11 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/swipe/JSwipeConstant.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.swipe;
2 |
3 | /**
4 | * author : Jiang Pengyong
5 | * time : 2019-08-18 15:11
6 | * email : 56002982@qq.com
7 | * desc : 侧滑常量
8 | * version : 1.0.0
9 | */
10 |
11 | public interface JSwipeConstant {
12 |
13 | int LEFT = 1;
14 | int RIGHT = 1 << 1;
15 | int CONTENT = 1 << 2;
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/swipe/JSwipeViewHolder.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.swipe;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.widget.FrameLayout;
6 |
7 | import androidx.recyclerview.widget.RecyclerView;
8 |
9 | import com.zinc.librecycleview.R;
10 |
11 | /**
12 | * author : Jiang Pengyong
13 | * time : 2018-04-08 14:37
14 | * email : 56002982@qq.com
15 | * desc : 侧滑的ViewHolder
16 | * version : 1.0.0
17 | */
18 |
19 | public abstract class JSwipeViewHolder extends RecyclerView.ViewHolder {
20 |
21 | private static final int NONE = -1;
22 |
23 | private FrameLayout flLeftMenu;
24 | private FrameLayout flContent;
25 | private FrameLayout flRightMenu;
26 |
27 | private JSwipeItemLayout swipeItemLayout;
28 |
29 | public JSwipeViewHolder(View itemView) {
30 | super(itemView);
31 |
32 | swipeItemLayout = itemView.findViewById(R.id.swipe_item_layout);
33 | flLeftMenu = itemView.findViewById(R.id.fl_left_menu);
34 | flContent = itemView.findViewById(R.id.fl_content);
35 | flRightMenu = itemView.findViewById(R.id.fl_right_menu);
36 |
37 | flLeftMenu.removeAllViews();
38 | flRightMenu.removeAllViews();
39 | flContent.removeAllViews();
40 |
41 | if (getLeftMenuLayout() != NONE) {
42 | LayoutInflater
43 | .from(itemView.getContext())
44 | .inflate(getLeftMenuLayout(), flLeftMenu, true);
45 |
46 | initLeftMenuItem(flLeftMenu);
47 | swipeItemLayout
48 | .getMenus()
49 | .put(JSwipeConstant.LEFT, flLeftMenu);
50 | }
51 |
52 | if (getRightMenuLayout() != NONE) {
53 | LayoutInflater
54 | .from(itemView.getContext())
55 | .inflate(getRightMenuLayout(), flRightMenu, true);
56 |
57 | initRightMenuItem(flRightMenu);
58 | swipeItemLayout
59 | .getMenus()
60 | .put(JSwipeConstant.RIGHT, flRightMenu);
61 | }
62 |
63 | LayoutInflater.from(itemView.getContext())
64 | .inflate(getContentLayout(), flContent, true);
65 | initContentItem(flContent);
66 |
67 | initItem(swipeItemLayout);
68 |
69 | }
70 |
71 | public JSwipeItemLayout getSwipeItemLayout() {
72 | return swipeItemLayout;
73 | }
74 |
75 | /**
76 | * 获取左菜单布局
77 | *
78 | * @return 左菜单的 xml
79 | */
80 | public int getLeftMenuLayout() {
81 | return NONE;
82 | }
83 |
84 | /**
85 | * 获取右菜单布局
86 | *
87 | * @return 右菜单的 xml
88 | */
89 | public int getRightMenuLayout() {
90 | return NONE;
91 | }
92 |
93 | /**
94 | * 获取内容布局
95 | *
96 | * @return 内容的 xml
97 | */
98 | public abstract int getContentLayout();
99 |
100 | /**
101 | * 初始化左菜单项
102 | *
103 | * @param flLeftMenu 左菜单视图
104 | */
105 | public void initLeftMenuItem(FrameLayout flLeftMenu) {
106 |
107 | }
108 |
109 | /**
110 | * 初始化右菜单项
111 | *
112 | * @param flRightMenu 右菜单视图
113 | */
114 | public void initRightMenuItem(FrameLayout flRightMenu) {
115 |
116 | }
117 |
118 | /**
119 | * 初始化内容项
120 | *
121 | * @param flContent 内容视图
122 | */
123 | public void initContentItem(FrameLayout flContent) {
124 | }
125 |
126 | /**
127 | * 初始化视图
128 | *
129 | * @param frameLayout 包含[左菜单视图,内容视图,右菜单视图]
130 | */
131 | public abstract void initItem(FrameLayout frameLayout);
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/utils/LogUtils.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.utils;
2 |
3 | import android.util.Log;
4 |
5 | import com.zinc.jrecycleview.config.JRecycleViewManager;
6 |
7 | /**
8 | * author : Jiang Pengyong
9 | * time : 2019-08-16 14:09
10 | * desc : 日志打印
11 | * version : 1.0.0
12 | */
13 | public class LogUtils {
14 |
15 | private static final String TAG = "JRecycleView";
16 |
17 | public static void i(String tag, String msg) {
18 | if (JRecycleViewManager.getInstance().isDebug()) {
19 | Log.i(tag, msg);
20 | }
21 | }
22 |
23 | public static void d(String tag, String msg) {
24 | if (JRecycleViewManager.getInstance().isDebug()) {
25 | Log.d(tag, msg);
26 | }
27 | }
28 |
29 | public static void w(String tag, String msg) {
30 | if (JRecycleViewManager.getInstance().isDebug()) {
31 | Log.w(tag, msg);
32 | }
33 | }
34 |
35 | public static void v(String tag, String msg) {
36 | if (JRecycleViewManager.getInstance().isDebug()) {
37 | Log.v(tag, msg);
38 | }
39 | }
40 |
41 | public static void e(String tag, String msg) {
42 | if (JRecycleViewManager.getInstance().isDebug()) {
43 | Log.i(tag, msg);
44 | }
45 | }
46 |
47 | public static void i(String msg) {
48 | Log.i(TAG, msg);
49 | }
50 |
51 | public static void d(String msg) {
52 | Log.d(TAG, msg);
53 | }
54 |
55 | public static void w(String msg) {
56 | Log.w(TAG, msg);
57 | }
58 |
59 | public static void v(String msg) {
60 | Log.v(TAG, msg);
61 | }
62 |
63 | public static void e(String msg) {
64 | Log.i(TAG, msg);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/utils/MathUtil.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.utils;
2 |
3 | import android.graphics.PointF;
4 |
5 | /**
6 | * author : Jiang Pengyong
7 | * time : 2019-08-16 10:26
8 | * email : 56002982@qq.com
9 | * desc :
10 | * version : 1.0.0
11 | */
12 | public class MathUtil {
13 |
14 | /**
15 | * 获得两点之间的直线距离
16 | *
17 | * @param p1 PointF
18 | * @param p2 PointF
19 | * @return 两点之间的直线距离
20 | */
21 | public static float getTwoPointDistance(PointF p1, PointF p2) {
22 | return (float) Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
23 | }
24 |
25 | /**
26 | * 根据两个点(x1,y1)(x2,y2)的坐标算出斜率
27 | *
28 | * @param x1 x1
29 | * @param x2 x2
30 | * @param y1 y1
31 | * @param y2 y2
32 | * @return 斜率
33 | */
34 | public static Float getLineSlope(float x1, float x2, float y1, float y2) {
35 | if (x2 - x1 == 0) return null;
36 | return (y2 - y1) / (x2 - x1);
37 | }
38 |
39 | /**
40 | * 根据传入的两点得到斜率
41 | *
42 | * @param p1 PointF
43 | * @param p2 PointF
44 | * @return 返回斜率
45 | */
46 | public static Float getLineSlope(PointF p1, PointF p2) {
47 | if (p2.x - p1.x == 0) return null;
48 | return (p2.y - p1.y) / (p2.x - p1.x);
49 | }
50 |
51 | /**
52 | * Get middle point between p1 and p2.
53 | * 获得两点连线的中点
54 | *
55 | * @param p1 PointF
56 | * @param p2 PointF
57 | * @return 中点
58 | */
59 | public static PointF getMiddlePoint(PointF p1, PointF p2) {
60 | return new PointF((p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f);
61 | }
62 |
63 |
64 | /**
65 | * Get the point of intersection between circle and line.
66 | * 获取 通过指定圆心,斜率为lineK的直线与圆的交点。
67 | *
68 | * @param pMiddle The circle center point.
69 | * @param radius The circle radius.
70 | * @param lineK The slope of line which cross the pMiddle.
71 | * @return
72 | */
73 | public static PointF[] getIntersectionPoints(PointF pMiddle, float radius, Float lineK) {
74 | PointF[] points = new PointF[2];
75 |
76 | float radian, xOffset = 0, yOffset = 0;
77 | if (lineK != null) {
78 | radian = (float) Math.atan(lineK);
79 | xOffset = (float) (Math.sin(radian) * radius);
80 | yOffset = (float) (Math.cos(radian) * radius);
81 | } else {
82 | xOffset = radius;
83 | yOffset = 0;
84 | }
85 | points[0] = new PointF(pMiddle.x + xOffset, pMiddle.y - yOffset);
86 | points[1] = new PointF(pMiddle.x - xOffset, pMiddle.y + yOffset);
87 |
88 | return points;
89 | }
90 |
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/lib.recycleview/src/main/java/com/zinc/jrecycleview/utils/PointEvaluator.java:
--------------------------------------------------------------------------------
1 | package com.zinc.jrecycleview.utils;
2 |
3 | import android.animation.TypeEvaluator;
4 | import android.graphics.PointF;
5 |
6 | /**
7 | * author : Jiang Pengyong
8 | * time : 2019-08-16 10:25
9 | * email : 56002982@qq.com
10 | * desc : 点的估值器
11 | * version : 0.1.0
12 | */
13 | public class PointEvaluator implements TypeEvaluator