何为通用
用过RecyclerView
的都知道它没有为我们提供像ListView
中类似addHeaderView
,
addFooterView
,
setOnItemClickListener
,
setOnItemLongClickListener
的接口,另外还有底部自动加载更多,这些都是列表使用中很常见的功能,所以如果我们使用RecyclerView
来实现列表的话就需要自己实现这些功能。本文主要介绍这些通用功能的实现方式,使得RecyclerView
使用起来和ListView
一样方便。
点击事件
setOnItemClickListener,setOnItemLongClickListener
RecyclerView
中虽然没有提供上面这两个接口,但是给我们提供了另外一个接口:OnItemTouchListener
看这个接口的文档描述我们知道此接口可以对RecyclerView
中的手势进行监听处理,因此我们可以采用OnItemTouchListener+GestureDetector
来实现RecyclerView
的OnItemClick
和OnItemLongClick
。实现方式也比较简单,还是上代码吧…
[代码]java代码:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
|
addHeaderView,addFooterView
实现原理
前面写过一篇文章RecyclerView
下拉刷新上拉加载 介绍过RecyclerView
的上拉加载的实现方式,里面的上拉加载进度条其实也是RecyclerView
的一个FooterView
,其实现方式就是为LoadMoreView
设置了一个特殊的ItemViewType
来进行区分展示,因此我这里的HeaderView
和FooterView
也是通过为它们设置不同的ItemViewType
来进行区分展示。
我们知道ListView
中的addHeaderView
和addFooterView
都是可以添加多个View的,也就是说RecyclerView
中也会出现添加多个完全不同的HeaderView
或FooterView
,所以我们必须为添加的每个HeaderView
和FooterView
都设置一个ItemViewType
从而达到添加多个不同的HeaderView
或FooterView
的目的(如果所有的HeaderView
或FooterView
都设置同一个ItemViewType
的话只能显示一种View
的HeaderView
或FooterView
)。
实现步骤
知道了实现原理,我们再来理一下实现步骤:
1. 因为每个HeaderView
或FooterView
都需要对应一个ItemViewType
,所以我们需要分别为它们建立一个映射关系,我采用SparseArray
实现映射
2. 我们需要在添加HeaderView
或FooterView
的时候生成对应的ItemViewType
值,也就是我们需要定义一个ItemViewType
的生成规则,我采用了基准值+视图个数的方式生成ItemViewType
3. 自定义一个Adapter
继承自RecyclerView.Adapter
,重写里面的几个方法:onCreateViewHolder
,
onBindViewHolder
,
getItemViewType
,
getItemCount
4. getItemCount
方法中返回的数据总数显然是:HeaderView
总数
+FooterView
总数
+List
列表展示的数据总数
5. 重写onBindViewHolder
,getItemViewType
这两个方法时,显然需要根据position
判断当前位置是否为HeaderView
或是FooterView
,而根据展示顺序来看当0<=position<HeaderView
总数
时是HeaderView
,而当position>=(HeaderView
总数
+List
总数
)
时则是FooterView
,其余位置则是List
数据对应的View
6. 而重写onCreateViewHolder
方法时,则可用直接根据其方法参数viewType
在SparseArray映射中查找是否存在该类型的HeaderView
或是FooterView
,有则返回,没有则返回List数据展示的View
关键代码
分析完实现的步骤开始撸代码,下面是我实现的关键代码:
[代码]java代码:
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
|
RecyclerView使用注意
1. 这里需要注明一点RecyclerView
使用中的坑,如果RecyclerView
为LinearLayoutManager
时在onCreatViewHolder
中生成的View都必须关联上其parent
,也就是关联到RecyclerView
本身。我前面的一片文章记录了我遇到的这个问题RecyclerView
子View
宽度不充满父容器,所以在addHeaderView
和addFooterView
时也需要注意这个问题
2. 如果你的RecyclerView
的LayoutManager
是GridLayoutManager
或StaggeredGridLayoutManager
时,如果就这样添加HeaderView
或FooterView
,会发现HeaderView
或FooterView
不会独立的占据一行。这是因为设置了SpanSize
的缘故,所以我们需要针对这两种LayoutManager
进行处理,处理方式如下:
[代码]java代码:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
自动加载更多
自动加载更多也是列表显示中比较常见的一个功能,我们可以为RecyclerView
设置ScrollListener
监听来进行实现,具体实现的关键代码如下;
[代码]java代码:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|