1、RecyclerView的控件和定义
2、RecyclerView属性设置
3、RecyclerView优化和数据加载
4、三种显示方式
5、接口回调的使用
6、多布局

一.RecyclerView的介绍
RecyclerView是谷歌V7包下新增的控件,用来替代ListView的使用,在RecyclerView标准化了ViewHolder类似于ListView中convertView用来做视图缓.
先来说说RecyclerView的优点就是,他可以通过设置LayoutManager来快速实现listview、gridview、瀑布流的效果,而且还可以设置横向和纵向显示,添加动画效果也非常简单(自带了ItemAnimation,可以设置加载和移除时的动画,方便做出各种动态浏览的效果),也是官方推荐使用的.以下是官方的说明:

RecyclerView好处
①RecylerView封装了viewholder的回收复用,也就是说RecylerView标准化了ViewHolder,编写Adapter面向的是 ViewHolder而不再是View了,复用的 逻辑被封装了,写起来更加简单。
②提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecylerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。例如recyclerview不局限与下拉列表,它还支持GridView效果和瀑布流效果
③可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecylerView有其自己默认的实现。

涉及到的类
Adapter:使用RecyclerView之前,你需要一个继承自RecyclerView.Adapter的适配器,作用是将数据与每一个item的界面进行绑定。
LayoutManager:用来确定每一个item如何进行排列摆放,何时展示和隐藏。回收或重用一个View的时候,LayoutManager会向适配器请求新的数据来替换旧的数据,这种机制避免了创建过多的View和频繁的调用findViewById方法(与ListView原理类似)。

目前SDK中提供了三种自带的LayoutManager:

LinearLayoutManager 线性布局
GridLayoutManager 网格布局
StaggeredGridLayoutManager 瀑布流

RecyclerView.Adapter
①onCreateViewHolder()
这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。

②onBindViewHolder()
这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。

③getItemCount()
这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。

二.RecyclerView的使用

1、添加依赖
implementation 'com.android.support:recyclerview-v7:27.1.1'
2.然后是在XML文件用使用它
<android.support.v7.widget.RecyclerViewandroid:id="@+id/rv"android:layout_width="match_parent"android:layout_height="match_parent"/>

3.创建完布局之后在MainActivity中获取这个RecyclerView,并声明LayoutManager与Adapter,代码如下:

recyclerView = (RecyclerView) findViewById(R.id.recyclerView);  LinearLayoutManager layoutManager = new LinearLayoutManager(this );  //设置布局管理器  recyclerView.setLayoutManager(layoutManager);  //设置为垂直布局,这也是默认的  layoutManager.setOrientation(OrientationHelper. VERTICAL);  //设置Adapter  recyclerView.setAdapter( recycleAdapter);  //设置分隔线  recyclerView.addItemDecoration( new DividerGridItemDecoration(this ));  //设置增加或删除条目的动画  recyclerView.setItemAnimator( new DefaultItemAnimator());

4.创建适配器和ViewHolder

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {private final ArrayList<String> mData;private final Context mContext;private final LayoutInflater mInflater;private OnItemClickListener mListener;public MyAdapter(Context context,ArrayList<String> data) {this.mContext = context;this.mData = data;mInflater = LayoutInflater.from(context);}@NonNull@Overridepublic MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {//创建一个自定义ViewHolderView inflate = mInflater.inflate(R.layout.item, parent,false);ViewHolder viewHolder = new ViewHolder(inflate);return viewHolder;}@Overridepublic void onBindViewHolder(@NonNull MyAdapter.ViewHolder holder, final int position) {//将数据与界面绑定holder.mTv.setText(mData.get(position));if (position%2 == 0){holder.mIv.setImageResource(R.drawable.friend_circle_default);}else{holder.mIv.setImageResource(R.drawable.cate);}holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//这个方法被调用的时候,想要让MainActivity知道if (mListener != null){mListener.onItemClick(v,position);}}});}//1.定义一个接口public interface OnItemClickListener{void onItemClick(View view,int position);}//2.传递接口类实现对象public void setOnItemClickListener(OnItemClickListener listener){this.mListener = listener;}@Overridepublic int getItemCount() {//获取item数量return mData.size();}/*** RecyclerView 内部封装了VIewHolder的回收复用,标准化了ViewHolder,编写Adapter就是面向ViewHolder,而不是View*/public class ViewHolder extends RecyclerView.ViewHolder{private TextView mTv;private ImageView mIv;public ViewHolder(View itemView) {super(itemView);mTv = itemView.findViewById(R.id.tv);mIv = itemView.findViewById(R.id.iv);}}
}

三.RecyclerView 子条目点击监听–接口回调

1.定义接口
在哪里定义?
定义外部接口和内部接口都可以,google一般定义内部,所以我们也定义内部接口
接口里有什么方法
取决于我们要做什么,需要什么方法就定义什么

 //Adapter内部定义public interface OnItemClickListener{void onItemClick(View view,int position);}

2.设置传递接口类实现对象的方法

public void setOnItemClickListener(OnItemClickListener listener){this.mListener = listener;}

3.传递接口实现类对象

mAdapter.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(View view, int position) {Toast.makeText(MainActivity.this, "position:" + position, Toast.LENGTH_SHORT).show();startActivity(new Intent(MainActivity.this, MultiTypeActivity.class));}});

四.RecyclerView多布局
1.重写getItemViewType(),根据position返回item view的类型;
2.onCreateViewHolder(),根据viewType,返回包含对应item view的ViewHolder;
3.onBindViewHolder()中,调用getItemViewType(position),获取viewType,根据viewType,将ViewHolder强转对应的ViewHolder,并设置相应位置的数据

public class MyMultiAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {private final ArrayList<String> mData;private final Context mContext;private final LayoutInflater mInflater;private OnItemClickListener mListener;//item view 类型1private final static int VIEW_TYPE_ONE = 1;//item view 类型2private final static int VIEW_TYPE_TWO = 2;public MyMultiAdapter(Context context, ArrayList<String> data) {this.mContext = context;this.mData = data;mInflater = LayoutInflater.from(context);}@NonNull@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {//创建一个自定义ViewHolderif (viewType == VIEW_TYPE_ONE){//一种类型的viewType用一种ViewHolderView inflate = mInflater.inflate(R.layout.item, parent,false);ViewHolder viewHolder = new ViewHolder(inflate);return viewHolder;}else {View inflate = mInflater.inflate(R.layout.item2, parent,false);ViewHolder2 viewHolder2 = new ViewHolder2(inflate);return viewHolder2;}}@Overridepublic void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {//将数据与界面绑定int itemViewType = getItemViewType(position);if (itemViewType == VIEW_TYPE_ONE ){MyMultiAdapter.ViewHolder holder1 = (MyMultiAdapter.ViewHolder) holder;holder1.mTv.setText(mData.get(position));holder1.mIv.setImageResource(R.drawable.friend_circle_default);}else {MyMultiAdapter.ViewHolder2 holder2 = (ViewHolder2) holder;holder2.mTv.setText(mData.get(position));}holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//这个方法被调用的时候,想要让MainActivity知道if (mListener != null){mListener.onItemClick(v,position);}}});}public interface OnItemClickListener{void onItemClick(View view, int position);}public void setOnItemClickListener(OnItemClickListener listener){this.mListener = listener;}@Overridepublic int getItemCount() {//获取item数量return mData.size();}/*** RecyclerView 内部封装了VIewHolder的回收复用,标准化了ViewHolder,编写Adapter就是面向ViewHolder,而不是View*/public class ViewHolder extends RecyclerView.ViewHolder{private TextView mTv;private ImageView mIv;public ViewHolder(View itemView) {super(itemView);mTv = itemView.findViewById(R.id.tv);mIv = itemView.findViewById(R.id.iv);}}public class ViewHolder2 extends RecyclerView.ViewHolder{private TextView mTv;public ViewHolder2(View itemView) {super(itemView);mTv = itemView.findViewById(R.id.tv_item2);}}@Overridepublic int getItemViewType(int position) {//根据position返回itemview的类型if (position % 3 == 0){return VIEW_TYPE_ONE;}else {return VIEW_TYPE_TWO;}}}

五.RecyclerView和ListView对比
布局效果对比
常用功能与API对比
在Android L引入嵌套滚动机制(NestedScrolling)
ListView与RecyclerView的简单使用:
ListView:

  1. 继承重写BaseAdapter类;
  2. 自定义ViewHolder与convertView的优化(判断是否为null);

RecyclerView:

  1. 继承重写RecyclerView.Adapter与RecyclerView.ViewHolder
  2. 设置LayoutManager,以及layout的布局效果

区别:

  1. ViewHolder的编写规范化,ListView是需要自己定义的,而RecyclerView是规范好的;
  2. RecyclerView复用item全部搞定,不需要想ListView那样setTag()与getTag();
  3. RecyclerView多了一些LayoutManager工作,但实现了布局效果多样化;

布局效果:

ListView 的布局比较单一,只有一个纵向效果;
RecyclerView 的布局效果丰富, 可以在LayoutMananger中设置:线性布局(纵向,横向),表格布局,瀑布流布局
在RecyclerView 中,如果存在的LayoutManager不能满足需求,可以在LayoutManager的API中自定义Layout:
例如:scrollToPosition(), setOrientation(), getOrientation(), findViewByPosition()等等;

空数据处理:

在ListView中有个setEmptyView() 用来处理Adapter中数据为空的情况;但是在RecyclerView中没有这个API,所以在RecyclerView中需要进行一些数据判断来实现数据为空的情况;

HeaderView 与 FooterView:

在ListView中可以通过addHeaderView() 与 addFooterView()来添加头部item与底部item,来当我们需要实现下拉刷新或者上拉加载的情况;而且这两个API不会影响Adapter的编写;
但是RecyclerView中并没有这两个API,所以当我们需要在RecyclerView添加头部item或者底部item的时候,我们可以在Adapter中自己编写,根据ViewHolder的Type与View来实现自己的Header,Footter与普通的item,但是这样就会影响到Adapter的数据,比如position,添加了Header与Footter后,实际的position将大于数据的position;
局部刷新
在ListView中通常刷新数据是用notifyDataSetChanged() ,但是这种刷新数据是全局刷新的(每个item的数据都会重新加载一遍),这样一来就会非常消耗资源;
RecyclerView中可以实现局部刷新,例如:notifyItemChanged();
但是如果要在ListView实现局部刷新,依然是可以实现的,当一个item数据刷新时,我们可以在Adapter中,实现一个onItemChanged()方法,在方法里面获取到这个item的position(可以通过getFirstVisiblePosition()),然后调用getView()方法来刷新这个item的数据;

动画效果:

在RecyclerView中,已经封装好API来实现自己的动画效果;有许多动画API,例如:notifyItemChanged(), notifyDataInserted(), notifyItemMoved()等等;如果我们需要淑贤自己的动画效果,我们可以通过相应的接口实现自定义的动画效果(RecyclerView.ItemAnimator类),然后调用RecyclerView.setItemAnimator() (默认的有SimpleItemAnimator与DefaultItemAnimator);
但是ListView并没有实现动画效果,但我们可以在Adapter自己实现item的动画效果;
ItemTouchHelper:
创建ItemTouchHelper实例,然后在ItemTouchHelper.SimpleCallback(),然后在Callback中实现getMovementFlags(), onMove(), onSwiped(), 最后调用RecyclerView的attachToRecyclerView方法;

Item点击事件:

在ListView中有onItemClickListener(), onItemLongClickListener(), onItemSelectedListener(), 但是添加HeaderView与FooterView后就不一样了,因为HeaderView与FooterView都会算进position中,这时会发现position会出现变化,可能会抛出数组越界,为了解决这个问题,我们在getItemId()方法(在该方法中HeaderView与FooterView返回的值是-1)中通过返回id来标志对应的item,而不是通过position来标记;但是我们可以在Adapter中针对每个item写在getView()中会比较合适;
而在RecyclerView中,提供了唯一一个API:addOnItemTouchListener(),监听item的触摸事件;我们可以通过RecyclerView的addOnItemTouchListener()加上系统提供的Gesture Detector来实现像ListView那样监听某个item某个操作方法;

嵌套滚动机制:

在事件分发机制中,Touch事件在进行分发的时候,由父View向子View传递,一旦子View消费这个事件的话,那么接下来的事件分发的时候,父View将不接受,由子View进行处理;但是与Android的事件分发机制不同,嵌套滚动机制(Nested Scrolling)可以弥补这个不足,能让子View与父View同时处理这个Touch事件,主要实现在于NestedScrollingChild与NestedScrollingParent这两个接口;而在RecyclerView中,实现的是NestedScrollingChild,所以能实现嵌套滚动机制;
ListView就没有实现嵌套滚动机制;

RecyclerView的介绍相关推荐

  1. android之RecyclerView.Adapter介绍

    image.png

  2. 关于RecyclerView

    2019独角兽企业重金招聘Python工程师标准>>> 今天讨论ListView与RecyclerView的对比,搜索了资料,发现腾讯分享了两篇非常棒的文章.因为转载授权的原因,所以 ...

  3. 开源框架 ImageLoader +ListView+GridView+RecyclerView 浅解

    下载地址 链接:https://pan.baidu.com/s/1ebz99pcuvHg2bODgeOtSbg 提取码:ia39 一.导入jar包或者添加依赖 jar包地址 导入jar包:将下载的ja ...

  4. RecyclerView优秀文集

    来自:https://github.com/CymChad/CymChad.github.io RecyclerView优秀文集 收集RecyclerView优秀文章,持续更新欢迎提交pr,推荐sta ...

  5. Android控件知识点-RecyclerView(全网最详解)

    背景:笔者在开发Android 蓝牙通信,需要搜索蓝牙设备并且动态显示,这个时候就需要选取适合的相关视图控件了,最后兜兜转转还是觉得RecyclerView好用一些,本人也是在开发的过程中,搜索了很多 ...

  6. RecyclerView详细解释

    原文链接:http://www.haotianyi.win/2016/11/recyclerview%E8%AF%A6%E7%BB%86%E8%A7%A3%E9%87%8A.html Recycler ...

  7. ListView 和 RecyclerView 的使用

    ListView的讲解 ListView详细介绍与使用 前言介绍: 关于 ListView 我们大家都应该是非常的熟悉了,在 Android 开发中是经常用到的,今天就再来回顾一下,ListView ...

  8. Android RecyclerView实现瀑布流布局

    先看看效果: RecyclerView简单介绍: 1背景: 常规的ListView功能已经足够强大,但是还是存在一些问题,例如,每次都需要自己创建一个ViewHolder.并手动判断是否有缓存View ...

  9. RecyclerView完全解析,让你从此爱上它(二十八)

    RecyclerView完全解析,让你从此爱上它(二十八) 2015-11-20      0 个评论   来源: 专注移动开发,项目管理.jiangqqlmj   收藏   我要投稿 (一).前言: ...

最新文章

  1. 【ACM】杭电OJ 2028
  2. VTK:几何对象之CellTypeSource
  3. idea中git如何切换到master_IDEA中Git的使用
  4. java addall 不能传null_null 之AddAll、Add和Boolean
  5. 适用于Mac的WinX HD视频转换器:视频转换教程
  6. 关于XML字符串和XML Document之间的转换
  7. c语言中根号绝对值,根号的绝对值怎么算?
  8. 10万+标注数据开放!驾驶员不良驾驶识别/电动车进电梯检测/渣土车车牌识别/反光衣识别等8大赛题详解来了!...
  9. VIM编辑器配置文件修改
  10. 解决:使用@符号,报错:找不到模块“@”或其响应的类型声明。
  11. Airbnb如何冲破租赁平台两大弊端的封锁而获得成功
  12. Oracle数据库查询十个小技巧
  13. 智能云门禁解决方案来了
  14. python操作数据库工具类
  15. jenv add “ln No such file or directory“解决办法
  16. [转载]茶话之四:政和工夫英伦打李鬼
  17. TP-Link WR703N升级64M内存+外接SMA天线+刷OpenWRT(2)升级内存
  18. Unity报错解决方法
  19. arduino连接ESP8266-01发微信消息,消息提醒等
  20. 【转】SAP物料主档关键栏位

热门文章

  1. 记一次requestAnimationFrame之后页面崩溃、内存泄漏问题
  2. js中的内存溢出和内存泄漏
  3. 数字电路和模拟电路-5组合逻辑电路分析与设计
  4. truncate table 用法
  5. 【JMS】JMS支持的模式讲解
  6. 使用Aspose.Words设置word文档多倍行距
  7. 在C#中给word文档加密和解密全过程
  8. 在C++中检测和转换字节序(ENDIAN)
  9. libpng warning: iCCP: known incorrect sRGB profile 警告,问题解决
  10. 关于举办“第五届全国现代物流绿色包装与循环共用大会”的通知