原文链接:https://blog.csdn.net/u012721519/article/details/54692366

一、RecycleView简要介绍

RecycleView是support-v7包中的新组件,是一个强大的滑动组件。相比于ListView和GridView具有很多让开发者喜欢的优点,如:数据绑定,Item的创建和View的回收复用机制等。但RecycleView更加高级灵活,当我们数据因为用户事件或者网络事件发生改变的时候也能很好的进行显示。RecycleView最主要的特点就是复用。
二、RecycleView与ListView区别

RecycleView是ListView的升级版,与经典的ListView相比,同样具有item的回收复用功能。

1.RecycleView封装了ViewHolder的回收复用,标准化了ViewHolder,编写Adapter面向的是ViewHolder,而不是View,高度解耦,复用的逻辑被封装,给编写代码带来更大的方便。

2.RecycleView提供了一种插拔式的体验,高度解耦,异常灵活,为了来控制item的显示,RecycleView针对一个Item的显示专门抽取了相应的类,使其扩展性非常强。

3.可以控制Item增减动画,可以通过ItemAnimation来进行控制。当然,RecycleView有其自己默认的实现方式。

4.使用LayoutManager来确定每一个item的排列方式。

5.在使用RecycleView之前,需要继承RecycleView.Adapter适配,将数据与每个item进行绑定。

6.利用LayoutManager确定每一个item如何摆放、何时展示与隐藏。或者回收复用View的时候,LayoutManager回想适配器请求新的数据来替换以前的数据,该机制避免了创建过多的View和频繁调用Id方法。

三、Recycle基本用法

1.在项目gradle下添加依赖。

compile 'com.android.support:recyclerview-v7:25.0.1'

2.实现RecycleView布局。

<android.support.v7.widget.RecyclerViewandroid:id="@+id/id_recyclerview"android:divider="#ffff0000"android:dividerHeight="10dp"android:layout_width="match_parent"android:layout_height="match_parent" />

3.设置布局管理器。布局主要有三种实现方式,本文采用流式布局进行解析。

mRecyclerView.setLayoutManager(new LinearLayoutManager(this));    //线性布局
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));     //网格
mRecyclerView.setLayoutManager(newStaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));     //流式布局

4.设置Adapter与ViewHolder进行事件绑定。

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {ViewGroup.LayoutParams lp = holder.tv.getLayoutParams();if(position != 0 && position < mDatas.size()){lp.height = mHeights.get(position);holder.tv.setLayoutParams(lp);}holder.tv.setText(mDatas.get(position));}

5.setAdapter与设置分割线、Item动画。

mAdapter = new HomeAdapter(this, mDatas);mAdapter.setOnItemClickListener(this);mRecyclerView.setAdapter(mAdapter);//设置默认分割线
//        mRecyclerView.addItemDecoration(new DividerItemDecoration(this,
//                DividerItemDecoration.VERTICAL));mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));//设置Item动画mRecyclerView.setItemAnimator(new DefaultItemAnimator());

6.初始化数据。

private void initListData() {mDatas = new ArrayList<String>();for (int i = 'A'; i <= 'z'; i++) {mDatas.add("" + (char) i);}
}

7.设置Item点击事件(增加Item)。RecycleView没有像ListView一样给我提供一个onItemClickListener内置监听器,当我们点击item触发事件的时候会回调相关方法,不过我们可以改造Adapter以达到我们的目的。

holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {int pos = holder.getLayoutPosition();listener.OnItemClick(holder.itemView, pos);addData(pos);}
});
public void addData(int position)
{mDatas.add(position, "Insert One");notifyItemInserted(position);
}

8.设置长按点击事件(移除Item)。同7一样,主要是使用RecycleView方法添加和删除数据。与ListView不同的是,ListView在数据发生变化的时候采用的是notifyDatasetChange方法刷新数据,但RecycleView采用更高级的方法notifyItemInserted(position)和notifyItemRemoved(position)来进行添加和删除的数据刷新。

holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View view) {int pos = holder.getLayoutPosition();listener.onItemLongClick(holder.itemView, pos);removeData(pos);return false;}
});
public void removeData(int position)
{mDatas.remove(position);notifyItemRemoved(position);
}

9.分割线的封装。

package example.com.demo_recycleview;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {private static final int[] ATTRS = new int[] { android.R.attr.listDivider };private Drawable mDivider;public DividerGridItemDecoration(Context context){final TypedArray array = context.obtainStyledAttributes(ATTRS);mDivider = array.getDrawable(0);array.recycle();}@Overridepublic void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state){drawHorizontal(c, parent);drawVertical(c, parent);}private int getSpanCount(RecyclerView parent){// 列数int spanCount = -1;RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();if (layoutManager instanceof GridLayoutManager){spanCount = ((GridLayoutManager) layoutManager).getSpanCount();} else if (layoutManager instanceof StaggeredGridLayoutManager){spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();}return spanCount;}public void drawHorizontal(Canvas c, RecyclerView parent){int childCount = parent.getChildCount();for (int i = 0; i < childCount; i++){final View child = parent.getChildAt(i);final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();final int left = child.getLeft() - params.leftMargin;final int right = child.getRight() + params.rightMargin+ mDivider.getIntrinsicWidth();final int top = child.getBottom() + params.bottomMargin;final int bottom = top + mDivider.getIntrinsicHeight();mDivider.setBounds(left, top, right, bottom);mDivider.draw(c);}}public void drawVertical(Canvas c, RecyclerView parent){final int childCount = parent.getChildCount();for (int i = 0; i < childCount; i++){final View child = parent.getChildAt(i);final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();final int top = child.getTop() - params.topMargin;final int bottom = child.getBottom() + params.bottomMargin;final int left = child.getRight() + params.rightMargin;final int right = left + mDivider.getIntrinsicWidth();mDivider.setBounds(left, top, right, bottom);mDivider.draw(c);}}private boolean isLastColum(RecyclerView parent, int pos, int spanCount,int childCount){RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();if (layoutManager instanceof GridLayoutManager){if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边{return true;}} else if (layoutManager instanceof StaggeredGridLayoutManager){int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();if (orientation == StaggeredGridLayoutManager.VERTICAL){if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边{return true;}} else{childCount = childCount - childCount % spanCount;if (pos >= childCount)// 如果是最后一列,则不需要绘制右边return true;}}return false;}private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,int childCount){RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();if (layoutManager instanceof GridLayoutManager){childCount = childCount - childCount % spanCount;if (pos >= childCount)// 如果是最后一行,则不需要绘制底部return true;} else if (layoutManager instanceof StaggeredGridLayoutManager){int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();// StaggeredGridLayoutManager 且纵向滚动if (orientation == StaggeredGridLayoutManager.VERTICAL){childCount = childCount - childCount % spanCount;// 如果是最后一行,则不需要绘制底部if (pos >= childCount)return true;} else// StaggeredGridLayoutManager 且横向滚动{// 如果是最后一行,则不需要绘制底部if ((pos + 1) % spanCount == 0){return true;}}}return false;}@Overridepublic void getItemOffsets(Rect outRect, int itemPosition,RecyclerView parent){int spanCount = getSpanCount(parent);int childCount = parent.getAdapter().getItemCount();if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部{outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);} else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边{outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());} else{outRect.set(0, 0, mDivider.getIntrinsicWidth(),mDivider.getIntrinsicHeight());}}
}

四、效果展示

             

五、源码下载

地址:http://download.csdn.net/detail/u012721519/9743570

【转载】RecycleView使用详解相关推荐

  1. [转载]HTTP协议详解

    当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为它让我们理解了We ...

  2. [转载]Spring配置文件详解一:

    2019独角兽企业重金招聘Python工程师标准>>> 原文地址:Spring配置文件详解一:<context:annotation-config/>与<conte ...

  3. Android recycleview使用详解,recycleview实现九宫格布局即横向排列,recycleview设置item占位数量大号item或小号item

    1.添加recycleview依赖 compile('com.android.support:recyclerview-v7:25.1.1') {force = true } 2.item.xml & ...

  4. [转载] Linux 内核进程详解之二: bdi-default

    原文链接: Linux 内核进程详解之二: bdi-default 转载说明 (最后更新于: 2019-04-03, 12:26:50) 转载本文的原意仅是为了理解 "bdi" 所 ...

  5. 【转载】Transformer详解

    转载于https://blog.csdn.net/Tink1995/article/details/105080033 文章目录 1.前言 2.Transformer 原理 2.1 Transform ...

  6. RecycleView Layout 详解

    前提 我们以RecycleView 的宽高都是Match_Parent作为前提去分析,这样onMeasure方法就不会调用dispatchStep1.dispatchStep2.我们只看onLayou ...

  7. 转载——java synchronized详解

    文章来源:http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html 转载于:https://www.cnblogs.com/ins ...

  8. [转载] Java泛型详解:<T>和Class<T>的使用。泛型类,泛型方法的详细使用实例

    参考链接: Java中的main()函数是强制性的吗 一.引入 1.泛型是什么 首先告诉大家ArrayList就是泛型.那ArrayList能完成哪些想不到的功能呢?先看看下面这段代码: [java] ...

  9. 转载:jsonp详解

    json相信大家都用的多,jsonp我就一直没有机会用到,但也经常看到,只知道是"用来跨域的",一直不知道具体是个什么东西.今天总算搞明白了.下面一步步来搞清楚jsonp是个什么玩 ...

最新文章

  1. 11月百度面试题(社招)
  2. 13.Java核心技术—内部类
  3. P1681 最大正方形 Iand II
  4. ajax 公共请求头部,ajax请求中全局增加请求头,如常见的token
  5. 用java做出两行三列的表格_Java中,使用HSSFSheet创建excel模板如何创建一列两行的数据?...
  6. Java知识整理——反射
  7. 阿里Sentinel控制台源码修改-对接Apollo规则持久化
  8. 初一模拟赛总结(5.11)
  9. 管理者必看!深度剖析BI与数据仓库,企业能否成功转型就看它
  10. 偶然搜索看到的杂谈——什麼東西是.NET程序員可以掌握並且可倚仗十年而不管微軟存在與否的技術呢?...
  11. PowerShell 笔记
  12. Lodop在页面获取打印机列表 选择打印机预览
  13. 2008 China MVP Open Day 小记
  14. Kubernetes详解(十八)——Pod就绪性探针实战
  15. 条形码图像生成库barcodelib使用介绍
  16. win 平台上排名第二的下载工具——IDM
  17. 柯桥托业TOEIC考试和PETS哪个含金量高?
  18. Elasticsearch顶尖高手系列:高手进阶篇(一)
  19. (zhuan)富文本 Attributes 下划线、删除线等
  20. linux nvme文件系统,Intel NVMe驱动器扇区大小不是4096的xfs文件系统的性能下降

热门文章

  1. 05.概念数据模型CDM
  2. Tita 如何助力组织目标层层落地
  3. 让智能更落地,让中台更智能
  4. 世界上只有三种人:程序猿人和男人女人
  5. ssm校园拼车服务系统毕业设计源码211633
  6. Play Framework 2.5.x 测试环境搭建
  7. 【活体检测】人脸活体检测、红外人脸数据集整理
  8. html 字体图标转换工具,字体转换器
  9. 职场“女神”,绝不会有的12个习惯
  10. Spring —— 基于注解的Aop在同一类下产生嵌套时切面不生效问题产生原因及解决