RecyclerView使用详解

来源:互联网 发布:建筑作品集知乎 编辑:程序博客网 时间:2024/06/05 20:57

RecyclerView是Android 5.x版本中新添加的一个全新控件,他比ListView,GridView更加的灵活,我们能够使用RecyclerView就完成ListView,GridView所做的工作,同时使用RecyclerView也能非常方便的实现瀑布流的效果。

一.竖屏ListView,横屏GridView效果

MainActivity代码:


首先获取到手机屏幕的宽高,如果width<height,那就展示一个ListView,如果width>height,那就展示一个4列的GridView。

MyRecyclerViewAdapter代码:


由于RecyclerView并没有像ListView一样给每个Item设置点击监听事件,所以我们需要自己实现对RecyclerView的点击监听。实现的方法可以是在我们的MyRecyclerViewAdapter中去为点击事件提供一个回调。

DividerItemDecoration代码(为ListView添加分割线):


DividerGridItemDecoration代码(为GridView添加分割线):


RecyclerView本身并不支持divider属性,所以如果我们不做定制,RecyclerView的每个Item之间是不会有分割线的,但是我们可以通过addItemDecoration()来定制自己的分割线,addItemDecoration()接收的参数是个ItemDecoration对象,我们可以自定义一个DividerItemDecoration类继承自ItemDecoration,在这个类中完成分割线的定制。

二.实现瀑布流效果

StaggeredGridActivity代码:


StaggeredGridAdapter代码:


其实瀑布流的实现和GridView的实现基本一致,只是瀑布流的每个Item的高不一样,所以这里在Adapter中动态的设置每个Item的高,在onBindViewHolder()中我们用到了LayoutParams方法,这里需要注意的是LayoutParams有很多不同的包,导包的时候一定要导对应的包。不然会报类型不匹配的错误。

三.添加、删除Item

1.删除:


2.添加:


设置动画:


四.点击监听(onClick,onLongClick)

如何实现RecyclerView的点击事件在上面的代码已经给出,上面的代码中如果是点击,则显示一条Toast,如果是长按则删除对应的Item。

点击事件处理中遇到的2个问题:

1.长按删除后也会显示非长按点击的Toast:

原因:一开始在setOnLongClickListener中返回了false,这样这个点击事件还会在向下传递,就会传递到setClickListener中,如果返回了true,则代表这次点击事件在setOnLongClickListener中就被消费了,不会再往下传递。(个人理解,有待验证...)可以参考下之前的文章 

OnTouch事件ACTION_DOWN,ACTION_MOVE,ACTION_UP的事件拦截

解决:setOnLongClickListener中return true。

2.长按删除后出现数据错乱:

原因:StaggeredGridAdapter的removeItem()方法中,我们对Item的删除使用了notifyItemRemoved(int position)方法,这是RecyclerView为我们提供的带动画的删除方法,但是这个方法只是删除了界面上的Item,为保持数据的一致,我们还需要删除数据源中对应的数据,即dataList.remove(position)。如果对Item的删除仅仅这样处理的话,你会发现再去做删除操作时会发生数据的错乱,导致这个的原因是,我们在做完删除处理后并没有对RecyclerView进行刷新,所以会导致RecyclerView显示的数据与数据源不一致

解决:解决这个问题的办法就是在删除数据后我们就对RecyclerView刷新一次。RecyclerView和ListView一样,有notifyDataSetChanged()方法,但是使用这个方法进行刷新我们就无法看到删除动画了,原因是调用notifyDataSetChanged()刷新屏幕上显示的所有item的话,必然也会刷新当前正在执行动画的那个Item,这样导致的结果是前面的动画还没执行完它马上又被刷新了,动画就看不见了。这里我们可以用notifyItemRangeChanged(int position, int itemCount())方法,只需要从被删除的Item后面开始刷新就可以了,这样就保持了原有的删除动画。







2 0