【 Android(安卓)】RecyclerView 使用方法总结
题外话:3月初的时候
RecyclerView
使用方法总结开始被我公开在GitHub
上,前后反反复复的添加修改将自己对RecyclerView
的认识全面的写出来。网上也有很多RecyclerView
的开源库,如果你嫌麻烦可以直接用那些大神写的库,但是随着Android
版本的升级那些开源库如果不更新就会出现大大小小的问题,到时候会很烦。我总结的方法是最原生最Android
的,从根上告诉你这个地方应该怎样去实现。
官方指南:
https://developer.android.google.cn/guide/topics/ui/layout/recyclerview.html
示例项目已上传至GitHub
(如果对你有帮助请Star
,谢谢):
https://github.com/cnwutianhao/RecyclerView
文章分三大部分:入门篇、进阶篇、拓展篇
导入必要的库:
implementation 'com.android.support:recyclerview-v7:27.1.0'
一、入门篇
- 纵向布局
- 横向布局
- 网格布局
1. 纵向布局
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/vertical
示例图:
纵向布局.gif
2. 横向布局
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/horizontal
示例图:
横向布局.gif
3. 网格布局
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/grid
示例图:
网格布局.gif
总结:
纵向布局、横向布局、网格布局的item
可以说相差微乎其微,关键区别在于setLayoutManager()
的写法不同:
纵向布局recyclerview.setLayoutManager(new LinearLayoutManager(this));或LinearLayoutManager manager = new LinearLayoutManager(this);manager.setOrientation(LinearLayoutManager.VERTICAL);recyclerview.setLayoutManager(manager);
横向布局LinearLayoutManager manager = new LinearLayoutManager(this);manager.setOrientation(LinearLayoutManager.HORIZONTAL);recyclerview.setLayoutManager(manager);
网格布局recyclerview.setLayoutManager(new GridLayoutManager(this, 横排数量));或GridLayoutManager manager = new GridLayoutManager(this, 横排数量);recyclerview.setLayoutManager(manager);
二、进阶篇
- 点击
- 分组
- 顶部悬浮(吸顶)
- 拖动
- 滑动删除
- 下拉刷新
- 上拉加载
- 双向滑动
- 居中对齐
- 展开和收缩
- 瀑布流
- 时间轴
- 添加 Footer(包含 List 样式 和 网格样式)
- 添加 Header(包含 List 样式 和 网格样式)
1. 点击
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/click
示例图:
点击.gif
总结:
RecyclerView
的点击事件有两种写法:
① 在Adapter
里面直接对控件做点击事件
② 写接口,在Activity
或Fragment
上实现接口中定义的方法
在 Adapter 里面直接对控件做点击事件@Overridepublic void onBindViewHolder(@NonNull XxxViewHolder holder, int position) { holder.控件名.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO: } });}
在 Adapter 里写接口public interface OnItemClickListener { void onItemClick(参数类型 参数名 , ...);}private OnItemClickListener mListener;public XxxAdapter(Context context, OnItemClickListener listener) { mContext = context; mListener = listener;}@Overridepublic void onBindViewHolder(@NonNull XxxViewHolder holder, int position) { holder.控件名.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mListener.onItemClick(content); } });}在 Activity 或 Fragment 上实现接口中定义的方法public class XxxActivity extends AppCompatActivity implements XxxAdapter.OnItemClickListenerXxxAdapter adapter = new XxxAdapter(context, this);@Overridepublic void onItemClick(String content) { // TODO:}
2. 分组
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/group
示例图:
分组.gif
总结:
RecyclerView
分组的写法有很多种,我会在分组
、顶部悬浮
、联动
中给出不同的写法。
第一种分组写法也是最简单的一种,将组名和内容写在同一个布局,在onBindViewHolder
里根据位置来进行组名的显示与隐藏:
if (position == 0) { holder.组名.setVisibility(View.VISIBLE);} else { if (list.get(position).get组().equals(list.get(position - 1).get组())) { holder.组名.setVisibility(View.GONE); } else { holder.组名.setVisibility(View.VISIBLE); }}
3. 顶部悬浮(吸顶)
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/sticky
示例图:
顶部悬浮.gif
总结:
顶部悬浮也涉及到了分组,第二种分组写法将组名和RecyclerView
同级写,item
里面组名和内容写法与之前的分组类似,然后在onBindViewHolder
里判断是否是第一个头部,有无头部来进行判断:
组名和 RecyclerView 同级写<?xml version="1.0" encoding="utf-8"?> item 里面写组名和内容<?xml version="1.0" encoding="utf-8"?> 判断是否是第一个头部,有无头部来进行判断public static final int FIRST_STICKY_VIEW = 1;public static final int HAS_STICKY_VIEW = 2;public static final int NONE_STICKY_VIEW = 3;if (position == 0) { holder.组名.setVisibility(View.VISIBLE); holder.组名.setText(实体类.组); holder.itemView.setTag(FIRST_STICKY_VIEW);} else { if (!TextUtils.equals(实体类.组, mList.get(position - 1).组)) { holder.组名.setVisibility(View.VISIBLE); holder.组名.setText(实体类.组); holder.itemView.setTag(HAS_STICKY_VIEW); } else { holder.组名.setVisibility(View.GONE); holder.itemView.setTag(NONE_STICKY_VIEW); }}
4. 拖动
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/drag
示例图:
拖动.gif
总结:
关键字:ItemTouchHelper
5. 滑动删除
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/swipe
示例图:
滑动删除.gif
总结:
关键字:ItemTouchHelper
6. 下拉刷新
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/refresh
示例图:
下拉刷新.gif
总结:
关键字:swipeRefreshLayout.setOnRefreshListener
7. 上拉加载
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/load
示例图:
上拉加载.gif
总结:
关键字:recyclerview.addOnScrollListener
,在onScrollStateChanged
里判断RecyclerView
的状态是空闲时,同时是最后一个可见的item
时才加载,在onScrolled
里获取最后一个可见的item
。
8. 双向滑动
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/slide
示例图:
双向滑动.gif
总结:
在Adapter
的getItemViewType
里判断是哪种布局,在onBindViewHolder
里分别对应自己的ViewHolder
。
9. 居中对齐
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/snaphelper
示例图:
居中对齐.gif
总结:
关键字:SnapHelper
10. 展开和收缩
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/expandcollapse
示例图:
展开和收缩.gif
总结:
在item
里将主内容和副内容写出来,通关点击item
副内容现实和隐藏来达到效果:
private int expandedPosition = -1;final boolean isExpanded = position == expandedPosition;holder.rlChild.setVisibility(isExpanded ? View.VISIBLE : View.GONE);holder.rlParent.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mViewHolder != null) { mViewHolder.rlChild.setVisibility(View.GONE); notifyItemChanged(expandedPosition); } expandedPosition = isExpanded ? -1 : holder.getAdapterPosition(); mViewHolder = isExpanded ? null : holder; notifyItemChanged(holder.getAdapterPosition()); }});
11. 瀑布流
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/waterfall
示例图:
瀑布流.gif
总结:
关键字:StaggeredGridLayoutManager
,示例代码取的是干货集中营福利的接口数据。
12. 时间轴
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/timeline
示例图:
时间轴.gif
总结:
在item
里写两种状态的布局,一种是当前状态的,另一种是之前状态的。在onBindViewHolder
里通过判断位置现实和隐藏来实现:
private static final int TYPE_HEADER = 0; private static final int TYPE_NORMAL = 1;if (getItemViewType(position) == TYPE_HEADER) { holder.tvHeaderLine.setVisibility(View.INVISIBLE); holder.tvTime.setTextColor(Color.BLACK); holder.tvContext.setTextColor(Color.BLACK); holder.tvDot.setBackgroundResource(R.drawable.timeline_dot_header);} else if (getItemViewType(position) == TYPE_NORMAL) { holder.tvHeaderLine.setVisibility(View.VISIBLE); holder.tvTime.setTextColor(Color.GRAY); holder.tvContext.setTextColor(Color.GRAY); holder.tvDot.setBackgroundResource(R.drawable.timeline_dot_normal);}
13. 添加 Footer(包含 List 样式 和 网格样式)
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/footer
示例图:
为 RecyclerView 添加 Footer(List 样式).gif
为 RecyclerView 添加 Footer(网格样式).gif
总结:
给RecyclerView
添加底部有两种形式,一种是List
型,另一种是网格型
。关键代码是在getItemViewType
里判断位置,然后在onCreateViewHolder
里面显示不同的布局。网格布局还用到了setSpanSizeLookup
。
13. 添加 Header(包含 List 样式 和 网格样式)
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/header
示例图:
为 RecyclerView 添加 Header(List 样式).gif
为 RecyclerView 添加 Header(网格样式).gif
总结:
与添加底部类似。
三、拓展篇
- 联动
左右联动
示例项目:
https://github.com/cnwutianhao/RecyclerView/tree/master/app/src/main/java/com/haocent/android/recyclerview/link
示例图:
左右联动.gif
总结:
参考 GangedRecyclerview,但是原著的代码对于那些理解RecyclerView
不透彻的不是很友好,都是自定义类,上手难,我对其进行了修改,去掉所有的自定义类,达到标准的书写格式,代码看上去很安卓。
更多相关文章
- Android(安卓)LayoutInflater原理分析,带你一步步深入了解View(一
- 弹出输入法软键盘,编辑框悬浮,及覆盖遮挡问题的解决
- Android软键盘弹起遮挡h5页面解决方法
- android学生管理系统,利用linerLayout,实现xml的读取和写入,以及按
- 切换tab的时候recyclerview滑动到最底部
- 【视频讲解】Android(安卓)ApiDemos示例解析App->Activity->Cust
- Android(安卓)Bugs——RecyclerView.Adapter java.lang.IllegalS
- Android(安卓)图表绘制 achartengine 示例解析
- qt for android环境搭建(Linux平台)