背景:列表控件在Android App开发中用到的场景很多。在以前我们用ListView,GradView,现在应该大多数开发者都已经在选择使用RecyclerView了,谷歌给我们提供了这些方便的列表控件,我们可以很容易的使用它们。但是在实际的场景中,我们可能还想要更多的能力,比如最常见的列表下拉刷新,上拉加载。上拉刷新和下拉加载应该是列表的标配吧,基本上有列表的地方都要具体这个能力。虽然刷新这个功能已经有各种各样的第三方框架可以选择,但是毕竟不是自己的嘛,今天我们就来实现一个自己的下拉刷新控件,多动手才能更好的理解。
效果图:
原理分析:
在coding之前,我们先分析一下原理,原理分析出来之后,我们才可以确定实现方案。
先上一张图,来个直观的认识:
在列表上面有个刷新头,随着手指向下拉,逐渐把顶部不可见的刷新头拉到屏幕中来,用户能看到刷新的状态变化,达到下拉刷新的目的。
通过分析,我们确定一种实现方案:我们自定义一个容器,容器里面包含两个部分。
1. 顶部刷新头。
2. 列表区域。
确定好布局容器之后,我们来分析刷新头的几种状态
把下拉刷新分为5中状态,通过不同状态间的切换实现下拉刷新能力。
状态间的流程图如下:
整个下拉刷新的流程就如图中所示。
流程清楚了之后,接下来就是编写代码实现了。
代码实现:
/**
* @author luowang8
* @date 2020-08-21 10:54
* @desc 下拉刷新控件
*/
public class PullRefreshView extends LinearLayout {
/**
* 头部tag
*/
public static final String HEADER_TAG = "HEADER_TAG";
/**
* 列表tag
*/
public static final String LIST_TAG = "LIST_TAG";
/**
* tag
*/
private static final String TAG = "PullRefreshView";
/**
* 默认初始状态
*/
private @State
int mState = State.INIT;
/**
* 是否被拖拽
*/
private boolean mIsDragging = false;
/**
* 上下文
*/
private Context mContext;
/**
* RecyclerView
*/
private RecyclerView mRecyclerView;
/**
* 顶部刷新头
*/
private View mHeaderView;
/**
* 初始Y的坐标
*/
private int mInitMotionY;
/**
* 上一次Y的坐标
*/
private int mLastMotionY;
/**
* 手指触发滑动的临界距离
*/
private int mSlopTouch;
/**
* 触发刷新的临界值
*/
private int mRefreshHeight = 200;
/**
* 滑动时长
*/
private int mDuring = 300;
/**
* 用户刷新监听器
*/
private OnRefreshListener mOnRefreshListener;
/**