(点击
上方公众号
,可快速关注)
来源:伯乐在线专栏作者 - 一叶飘舟
链接:http://android.jobbole.com/84060/
点击 → 了解如何加入专栏作者
很想给大家分享这个开源项目,但是由于工作的关系,没有抽出空,但还是趁着工作间隙写下了这篇博客。
简介
LRecyclerView是支持addHeaderView、 addFooterView、下拉刷新、分页加载数据的RecyclerView。
它对 RecyclerView 控件进行了拓展,给RecyclerView增加HeaderView、FooterView,并且不需要对你的Adapter做任何修改。
主要功能
-
下拉刷新、滑动到底部自动加载下页数据;
-
可以方便添加Header和Footer;
-
头部下拉样式可以自定义;
-
具备item点击和长按事件。
-
网络错误加载失败点击Footer重新请求数据;
-
可以动态为FooterView赋予不同状态(加载中、加载失败、滑到最底等)。
项目地址:https://github.com/jdsjlzx/LRecyclerView
感谢
如果我比别人看得远些,那是因为我站在巨人们的肩上。 (牛顿)
本开源控件是基于 HeaderAndFooterRecyclerView 开源项目而来,在原基础上进行了扩充。在此感谢cundong作者(github地址:https://github.com/cundong)。
效果图
Gradle
Step 1. 在你的根build.gradle文件中增加JitPack仓库依赖。
allprojects
{
repositories
{
jcenter
()
maven
{
url
"https://jitpack.io"
}
}
}
Step 2. 在你的model的build.gradle文件中增加LRecyclerView依赖。
compile
'com.github.jdsjlzx:LRecyclerView:1.0.0'
使用
添
加HeaderView
、
FooterView
mDataAdapter
=
new
DataAdapter
(
this
);
mDataAdapter
.
setData
(
dataList
);
mHeaderAndFooterRecyclerViewAdapter
=
new
HeaderAndFooterRecyclerViewAdapter
(
this
,
mDataAdapter
);
mRecyclerView
.
setAdapter
(
mHeaderAndFooterRecyclerViewAdapter
);
mRecyclerView
.
setLayoutManager
(
new
LinearLayoutManager
(
this
));
//add a HeaderView
RecyclerViewUtils
.
setHeaderView
(
mRecyclerView
,
new
SampleHeader
(
this
));
//add a FooterView
RecyclerViewUtils
.
setFooterView
(
mRecyclerView
,
new
SampleFooter
(
this
));
注意:
mHeaderAndFooterRecyclerViewAdapter = new HeaderAndFooterRecyclerViewAdapter(this, mDataAdapter);
HeaderAndFooterRecyclerViewAdapter提供了一些实用的功能,使用者不用关心它的实现,只需构造的时候把自己的mDataAdapter以参数形式传进去即可。
下拉刷新和加载更多
为了大家使用方便,将需要用的方法统一封装到接口LScrollListener中。
mRecyclerView
.
setLScrollListener
(
new
LRecyclerView
.
LScrollListener
()
{
@Override
public
void
onRefresh
()
{
}
@Override
public
void
onScrollUp
()
{
}
@Override
public
void
onScrollDown
()
{
}
@Override
public
void
onBottom
()
{
}
@Override
public
void
onScrolled
(
int
distanceX
,
int
distanceY
)
{
}
});
LScrollListener实现了nRefresh()、onScrollUp()、onScrollDown()、onBottom()、onScrolled五个事件,如下所示:
void
onRefresh
();
//pull down to refresh
void
onScrollUp
();
//scroll down to up
void
onScrollDown
();
//scroll from up to down
void
onBottom
();
//load next page
void
onScrolled
(
int
distanceX
,
int
distanceY
);
// moving state,you can get the move distance
-
onRefresh()——RecyclerView下拉刷新事件;
-
onScrollUp()——RecyclerView向上滑动的监听事件;
-
onScrollDown()——RecyclerView向下滑动的监听事件;
-
onBottom()——RecyclerView滑动到底部的监听事件;
-
onScrollDown()——RecyclerView正在滚动的监听事件;
加载更多(加载下页数据)
从上面的LScrollListener介绍中就可以看出,实现加载更多只要在onBottom()接口中处理即可。
下拉刷新
为了达到和Listview的下拉刷新效果,本项目没有借助SwipeRefreshLayout控件,而是在自定义RecyclerView头部实现的刷新效果。
这里的下拉刷新效果借鉴了开源库:AVLoadingIndicatorView
设置加载样式:
mRecyclerView
.
setRefreshProgressStyle
(
ProgressStyle
.
BallSpinFadeLoader
);
mRecyclerView
.
setArrowImageView
(
R
.
drawable
.
iconfont_downgrey
);
AVLoadingIndicatorView库有多少效果,LRecyclerView就支持多少下拉刷新效果,当然你也可以自定义下拉效果。
效果图:
下拉刷新逻辑处理:
从上面的LScrollListener介绍中就可以看出,实现下拉刷新只要在onRefresh()接口中处理即可。
加载网络异常处理
加载数据时如果网络异常或者断网,LRecyclerView为你提供了重新加载的机制。
效果图:
网络异常出错代码处理如下:
RecyclerViewStateUtils
.
setFooterViewState
(
getActivity
(),
mRecyclerView
,
getPageSize
(),
LoadingFooter
.
State
.
NetWorkError
,
mFooterClick
);
private
View
.
OnClickListener
mFooterClick
=
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
RecyclerViewStateUtils
.
setFooterViewState
(
getActivity
(),
mRecyclerView
,
getPageSize
(),
LoadingFooter
.
State
.
Loading
,
null
);
requestData
();
}
};
上面的mFooterClick就是我们点击底部的Footer时的逻辑处理事件,很显然我们还是在这里做重新请求数据操作。
点击事件和长按事件处理
在Hongyang前辈的博客中有下描述:
Click and LongClick
不过一个挺郁闷的地方就是,系统没有提供ClickListener和LongClickListener。
不过我们也可以自己去添加,只是会多了些代码而已。
实现的方式比较多,你可以通过mRecyclerView.addOnItemTouchListener去监听然后去判断手势, 当然你也可以通过adapter中自己去提供回调,这里我们选择后者,前者的方式,大家有兴趣自己去实现。
出自:http://blog.csdn.net/lmj623565791/article/details/45059587
Hongyang大神选择了后者,LRecyclerView早期选择了前者,经过实践总结,在adapter中实现点击事件会好点。
先看下怎么使用:
mHeaderAndFooterRecyclerViewAdapter
.
setOnItemClickLitener
(
new
OnItemClickLitener
()
{
@Override
public
void
onItemClick
(
View
view
,
int
position
)
{
}
@Override
public
void
onItemLongClick
(
View
view
,
int
position
)
{
}
});
原理就是实现viewHolder.itemView的点击和长按事件。由于代码过多就不贴出来了。
viewHolder.itemView是RecyclerView.Adapter中本身就具有的,不用额外定义。
源码如下:
public
static
abstract
class
ViewHolder
{
public
final
View
itemView
;
int
mPosition
=
NO_POSITION
;
int
mOldPosition
=
NO_POSITION
;
long
mItemId
=
NO_ID
;
int
mItemViewType
=
INVALID_TYPE
;
int
mPreLayoutPosition
=
NO_POSITION
;
设置空白View(setEmptyView)
mRecyclerView
.
setEmptyView
(
view
);
注意布局文件:
RelativeLayout
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
>
com
.
cundong
.
recyclerview
.
LRecyclerView
android
:
id
=
"@+id/list"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"fill_parent"
/>
include
android
:
id
=
"@+id/empty_view"
layout
=
"@layout/layout_empty"
android
:
visibility
=
"gone"
/>
RelativeLayout
>
分享
介绍完了LRecyclerView,似乎还少些什么,对了,那就是adapter了。
为了方便大家使用,分享个封装过的adapter。
public
class
ListBaseAdapter
T
extends
Entity
>
extends
RecyclerView
.
Adapter
{
protected
Context
mContext
;
protected
int
mScreenWidth
;
public
void
setScreenWidth
(
int
width
)
{
mScreenWidth
=
width
;
}
protected
ArrayList
mDataList
=
new
ArrayList
();
@Override
public
RecyclerView
.
ViewHolder onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
return
null
;
}
@Override
public
void
onBindViewHolder
(
RecyclerView
.
ViewHolder
holder
,
int
position
)
{
}
@Override
public
int
getItemCount
()
{
return
mDataList
.
size
();
}
public
List
getDataList
()
{
return
mDataList
;
}
public
void
setDataList
(
Collection
list
)
{
this
.
mDataList
.
clear
();
this
.
mDataList
.
addAll
(
list
);
notifyDataSetChanged
();
}
public
void
addAll
(
Collection
list
)
{
int
lastIndex
=