recycleView作为一个新的控件,那是有其特点的。在日常的使用中,基本是可以代替listView和gridview使用的,同时,它还多了一种瀑布流的展示方式。
因此,个人是比较推荐开发者在项目开发过程中逐渐的使用recycview代替listview和gridview的。大家也都知道产品经理的想法永远是捉摸不定的,这次跟你说要垂直布局,好,等你用listview做完之后,就又跟你说觉得网格布局可能会好一点!!!ok,当你终于把控件转换成gridview,修改了大量的代码之后。如果,产品经理再跟你说,最后决定还是使用瀑布流得我样式好了, 你会不会有种崩溃的感觉。反正,我是会和PM打一架再说的。。。
总而言之,竟然最后还是得从了PM,何不一开始就已经做好准备呢?
RecyclView就是这样的一款新的控件。它把布局管理,item动画等都独立暴露了出来。虽然代码是增加了,但是却变得更加的灵活了,像上面的需求你只需要改动一行代码就可以实现了。
关于RecyView如何使用,网上已经有太多的教程了,因此我也不再讲解,大家可以参考下面这位大神的文章:
这是一篇讲解的已经很详细的文章了,感谢作者的分享(还没有经过您的同意就放上你的文章,请见谅哈)
我这一片文章主要讲解的是如何优雅的增加下拉刷新和加载更多
关于下拉刷新
下拉刷新,在网上已经是有很多种的解决方案了,个人是比较喜欢通过在RecyView外层包裹一层 SwipeRefreshLayout来处理的。
SwipeRefreshLayout作为一个新的控件,使用简单,样式好看~
1.在xml中使用SwipeRefreshLayout包裹RecycleView
xml布局2.绑定控件
refresh_layout= (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout);
//添加刷新监听器
refresh_layout.setOnRefreshListener(newSwipeRefreshLayout.OnRefreshListener() {
@Override
public voidonRefresh() {
//加载数据
backURL();
}
});
3.在加载完数据之后,记得要在UI线程中调用
if(refresh_layout.isRefreshing()){
refresh_layout.setRefreshing(false);
}
记住这个操作只能在UI线程中执行,而且要是忘记了这个操作,那么即使在加载完数据之后,加载动画也不会停下来的
关于SwipRefreshLayout的更多用法可以参考
Android开发之SwipeRefreshLayout实现下拉刷新
总体的用法还是非常的简单易用的。好啦,下拉刷新就是这么的简单。
这一次的重点来了:
实现加载更多
网上实现加载更多的方法有很多。
今天由于想把项目的体积降下来,要砍掉一些没有必要的库,然后我就看到之前为了省时间直接就依赖了一个项目来实现瀑布流,然后瀑布流的布局在整个项目中,其实就只用了一次,就因为只用一次的东西而增加了一个依赖项目,真的是非常的蠢。所有我决定把这个依赖项目砍掉(并不是说这个项目不好)。既然要砍掉它,那就要找到它的替代品,所以我就把目光投向了RecycleView了,使用RecycleView实现瀑布流布局其实还是非常的快的,只要把
mLayoutManager=newStaggeredGridLayoutManager(2,OrientationHelper.VERTICAL);
就可以实现了。
关键还是在于实现下拉刷新和加载更多。下拉刷新在上面已经讲到怎么实现了,下面开始讲加载更多
在RecycleView中是没有onItemClickLinstener,OnItemLongClickListener以及加载更多等等的接口的。这一切都是要是自己实现的。本着不重复造轮子的精神,我先上google了一下。
发现大多是这样子的
拉刷新和上拉加载更多的RecyclerView,具有下拉和刷新动画
实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性、网格、瀑布流效果演示
What the hell?(并没有说这样子的方法不科学,只是可以更简单的解决)
我只是要简单的实现加载更多,有必要改动这么多,还要增加footerview,还有对RecycleView增加OnScrollLinstener来监听是否到达最后一条,还有用 mLayoutManager.findLast...关键是瀑布流的layoutmanager还没有这个接口。。。
于是就开始思考,竟然单击事件,长按事件可以通过订阅的方式来实现,那么加载更多是不是也可以?
如果我在初始化Adapter的时候就告诉Adapter:如果到了最后一条数据就告诉我,我来加载更多。
本着这样的想法,我在Adapter的初始化总增加了这一个参数
ps:在评论中有同学指出如果不满一屏可能会频繁触发loadMoreListener,解决方法就是增加一个 参数 pageNum,用于判断当前数据满不满
publicListAdapter_pic(Context context,List listData,
OnItemClickListener listener,in.yeyeapp.listeners.OnLoadMoreListener loadMoreListener,int pageNum) {
mListener= listener;
mContext= context.getApplicationContext();
this.mInflater= LayoutInflater.from(mContext);
this.data= listData;
this.pageNum = pageNum;
//订阅加载更多
this.loadMoreListener= loadMoreListener;
}
实现加载更多的具体做法
mAdapter=newListAdapter_pic(getActivity(),mListAlbums,(OnItemClickListener)this, newOnLoadMoreListener() {
@Override
public voidonLoadMore() {
currentPage++;
nextPage();
}
});
OnLoadMore的具体实现
public interfaceOnLoadMoreListener {
public voidonLoadMore();
}
接下来是在合适的时候触发事件。
仔细阅读Adapter的代码我们会发现 onBindViewHolder 是负责绘制ItemView的函数,所以它是知道它当前已经画到第一几个Item了,所以这项重任就交给它了
@Override
public voidonBindViewHolder(ViewHolder holder, intposition) {
//新增对 loadMoreListener 的非空判断,以及对数据数目满屏的判断,防止触发空指针错误及数据不满而频繁触发加载更多
if(position == getItemCount() -1 && loadMoreListener != null && getCount() > pageNum) {
//告诉订阅者已经到最后一个了,可以加载更多了
loadMoreListener.onLoadMore();
}
//其他绑定资源的操作
。。。
}
这样,加载更多就大功告成了!!!
基本在网络良好的情况下,是可以无感的加载更多的
做法也是比较的简单
核心的思想就是让Adapter在绘制到最后一个view的时候告诉主线程说可以更新了。。。
如果想让加载更多更快一步执行,可以通过修改判断的条件
if(position == getItemCount() -1)
可以在倒数第二个,倒数第三个等就可以加载更多,这样可以让用户更加感知不到加载的过程
不过就要注意数据的个数了
网友评论