以前那个账号,以后可能不用了,把文章搬过来!!!
效果预览
接受hi大头鬼hi的建议,来一个动态图,方便大家知道这是个什么东西。
动机
项目中,需要一个支持任意View的下拉刷新+上拉加载控件,GitHub上有很多现成的实现,如Android-PullToRefresh, android-Ultra-Pull-To-Refresh等,这些Library都非常优秀,但是Android-PullToRefresh
已经不在维护了,android-Ultra-Pull-To-Refresh本身并不支持上拉加载更多,经过一番纠结后决定自己写一个。
原理
无论是下拉刷新还是上拉加载更多,原理都是在内容View(ListView、RecyclerView…)不能下拉或者上划时响应用户的触摸事件,在顶部或者底部显示一个刷新视图,在程序刷新操作完成后再隐藏掉。
实现
既然要在头部和顶部添加刷新视图,我们的控件应该是个ViewGroup,我是直接继承FrameLayout,这个控件的名字叫NsRefreshLayout。然后我们需要定义一些属性,如是否自动触发上拉加载更多、刷新视图中的文字颜色等。
属性定义
<declare-styleable name="NsRefreshLayout">
<!--Loading视图背景颜色-->
<attr name="load_view_bg_color" format="color|reference"/>
<!--进度条颜色-->
<attr name="progress_bar_color" format="color|reference"/>
<!--进度条背景色-->
<attr name="progress_bg_color" format="color|reference"/>
<!--Loading视图中文字颜色-->
<attr name="load_text_color" format="color|reference"/>
<!--下拉刷新问题描述-->
<attr name="pull_refresh_text" format="string|reference"/>
<!--上拉加载文字描述-->
<attr name="pull_load_text" format="string|reference"/>
<!--是否自动触发加载更多-->
<attr name="auto_load_more" format="boolean"/>
<!--下拉刷新是否可用-->
<attr name="pull_refresh_enable" format="boolean"/>
<!--上拉加载是否可用-->
<attr name="pull_load_enable" format="boolean"/>
</declare-styleable>
属性读取
/**
* 初始化控件属性
*/
private void initAttrs(Context context, AttributeSet attrs) {
if (getChildCount() > 1) {
throw new RuntimeException("can only have one child");
}
loadingViewFinalHeight = NrlUtils.dipToPx(context, LOADING_VIEW_FINAL_HEIGHT_DP);
loadingViewOverHeight = loadingViewFinalHeight * 2;
if (isInEditMode() && attrs == null) {
return;
}
int resId;
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.NsRefreshLayout);
Resources resources = context.getResources();
//LoadView背景颜色
resId = ta.getResourceId(R.styleable.NsRefreshLayout_load_view_bg_color, -1);
if (resId == -1) {
mLoadViewBgColor = ta.getColor(R.styleable.NsRefreshLayout_load_view_bg_color,
Color.WHITE);
} else {
mLoadViewBgColor = resources.getColor(resId);
}
//加载文字颜色
resId = ta.getResourceId(R.styleable.NsRefreshLayout_load_text_color, -1);
if (resId == -1) {
mLoadViewTextColor = ta.getColor(R.styleable.NsRefreshLayout_load_text_color,
Color.BLACK);
} else {
mLoadViewTextColor = resources.getColor(resId);
}
//进度条背景颜色
resId = ta.getResourceId(R.styleable.NsRefreshLayout_progress_bg_color, -1);
if (resId == -1) {
mProgressBgColor = ta.getColor(R.styleable.NsRefreshLayout