概述
RecyclerView出来已经很长时间了,关于其的介绍也非常的多.作为ListView的升级版,它更加强大和灵活.
可以轻松的实现各种布局和动画,见其名,知其意.RecyclerView用于在有限窗口中展示大量数据集合的可复用的视图.
这里主要梳理一下Recyclerview的常用方法,示例Demo:BoBoMEe/AndroidDev
相关类
RecyclerView的灵活性,主要体现在各个类的职责分离上,RecyclerView不负责子View的展示与布局,只负责子view的回收与复用.其他的比如,子View的布局,装饰及动画都交由其他类来处理.
RecyclerView相关类及其作用
| 类 | 用途 |
|---|---|
| RecyclerView.ViewHolder | 装载子view数据的容器 |
| RecyclerView.LayoutManager | 布局管理器,负责子View的布局 |
| RecyclerView.Adapter | 适配器,负责处理数据与绑定视图 |
| RecyclerView.ItemDecoration | 装饰子view,如分割线、偏移等 |
| RecyclerView.ItemAnimator | 子view改变时的动画 |
基本使用
RecyclerView最简单的使用需要设置LayoutManager和Adapter,其他的都是可选项.简单使用流程可分为以下几步.
- 引入
1 | compile 'com.android.support:recyclerview-v7:23.4.0' |
1 | <android.support.v7.widget.RecyclerView |
- 设置
Adapter和LayoutManager
1 | RecyclerView mRecyclerView = (RecyclerView)findViewById(R.id.recycler_view); |
其中LinearLayoutManager代表线性显示.默认是方向为VERTICAL,LayoutManager抽象类有三个官方实现版本,分别是LinearLayoutManager(线性布局),GridLayoutManager(网格布局),StaggeredGridLayoutManager(瀑布流布局).
Adapter
不同于ListView的Adapter,Recyclerview的适配器强制使用ViewHolder模式.如下一个简单的Adapter实现
1 | public class RecyclerStringAdapter extends RecyclerView.Adapter<RecyclerViewholder> { |
其他用法
LayoutManager布局切换
我们知道LayoutManager主要负责子View的布局.通过设置不同的LayoutManager即可实现展现方式的改变.
如果不设置LayoutManager,数据将不会展现出来.
1 | //gridview的列数为3,orientation = VERTICAL |
1 | // 瀑布流的列数为3,orientation = VERTICAL |
1 | int orientation = mLinearLayoutManager.getOrientation(); |
LayoutManager常用方法
1 | //返回当前第一个可见 Item 的 position |
ItemAnimatorItem动画
用于设置子view的添加、移动、删除的相关动画效果.官方默认提供了一个DefaultItemAnimator,如果我们没有设置ItemAnimator,则默认就是DefaultItemAnimator,Recyclerview.Adapter提供了notifyDataSetChanged()、notifyItemInserted(index)、 notifyItemRemoved(position)、 notifyItemChanged(position)方法来刷新Recyclerview.这里可以看一下wasabeef/recyclerview-animators:实现了多种Recyclerview的Item动画
ItemDecorationItem装饰
通过mRecyclerView.addItemDecoration(new MarginDecoration(this));来给Item添加装饰,
ItemDecoration可以叠加,Recyclerview展示的时候会遍历所有的ItemDecoration并调用其绘制方法来对Item进行装饰.
ItemDecoration提供了三个方法用于定制装饰器:
1 | // 在Item条目绘制之前调用,如果不是指offset则被Item的内容所遮挡 |
Recyclerview多种布局
在ListView中为了实现多种布局,我们需要重写Adapter中的 getItemViewType和getViewTypeCount方法
而在Recyclerview中保留了getItemViewType方法,同时我们可以在onCreateViewHolder中根据不同的ViewType来创建不同的Holder
这里可以看一下hongyangAndroid/baseAdapter:万能的Adapter for ListView,RecyclerView,GridView
其中关于HeaderView及FooterwView的处理,同样也是通过ViewType来实现的,
在网格布局中,依靠了GridLayoutManager#setSpanSizeLookup方法来设置每个Item占多少个span,
在瀑布流不居中,通过给StaggeredGridLayoutManager.LayoutParams设置setFullSpan(true);来占满一行.
ItemTouchHelper
用于Recyclerview的触摸辅助操作,比如选中,移动,删除等事件的监听.
这里可以看一下: 可拖拽的RecyclerView,通过跟踪代码我们可以看到,ItemTouchHelper内部
主要是通过GestureDetectorCompat来处理触摸事件,并通过给Recyclerview设置OnItemTouchListener来实现效果
但是遗憾的是其中只 实现了onLongPress的监听.但是为我们设置Recyclerview的Item监听提供了一种新的思路
1 | //ItemTouchHelper#ItemTouchHelperGestureListener |
通过ItemTouchHelper实现Recyclerview的Click,LongClick,Select,Swipe,Drag等效果,
主要通过一个叫做ItemTouchHelper.Callback的类,示例:RvItemTouchHelperCallback
Recyclerview 选中模式
遗憾的是Recyclerview并不像Listview那样提供selectMode,但是在我们最初不适用selectMode的时候,我们是否采用过一种通过刷新Adapter来实现的方式呢
在Recyclerview中要实现选中模式,我们当然也要从Adapter下手,这里可以看一下Multi-Selection Mode for RecyclerView
其中的核心代码
1 | private SparseBooleanArray mSelectedItems; |
可以看到作者也是通过在Adapter中维护一个选中的集合来实现Recyclerview的选中模式的,
总结
Recyclerview不仅在灵活度和扩展性上都较AbsListView好,在项目中也得到了大量的使用,也还有大量的未知方法等着去实践,
比如Recyclerview的Scroll操作,RecycledViewPool.Recyclerview的上下拉刷新,
自定义LayoutManager、itemDecoration、itemAnimator等待
参考:
Android RecyclerView 使用完全解析 体验艺术般的控件
可拖拽的RecyclerView
Multi-Selection Mode for RecyclerView
Using the RecyclerView