什么是RecyclerView
        RecyclerView是Android 5.0 materials design中的组件之一,相应的还有CardView、Palette等。看名字我们就能看出一点端倪,没错,它主要的特点就是复用。我们知道,Listview中的Adapter中可以实现ViewHolder的复用。RecyclerView提供了一个耦合度更低的方式来复用ViewHolder,并且可以轻松的实现ListView、GridView以及瀑布流的效果。
 
RecyclerView的用法
        首先我们要gradle的依赖库中添加  compile 'com.android.support:recyclerview-v7:21.+'  。如果是eclipse直接导入android-support-v7-recyclerview.jar就可以了。
  1. /**
  2. * 设置Adapter
  3. */
  4. mRecyclerView.setAdapter(mListAdapter);
  5. /**
  6. * 设置布局管理器
  7. */
  8. mRecyclerView.setLayoutManager(linearLayoutManager);
  9. /**
  10. * 设置item分割线
  11. */
  12. mRecyclerView.addItemDecoration(itemDecoration);
  13. /**
  14. * 设置item动画
  15. */
  16. mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        使用RecyclerView,基本上要上面四步。相比ListView只需设置Adapter而言,RecyclerView的使用看起来似乎要复杂一些。但是它的可定制性更高了,你可以自己定制自己的分割线样式或者是item的的动画。
        下面我们看下如何使用RecyclerView简单实现ListView的效果。
activity:
  1. package com.bbk.lling.recyclerview;
  2.  
  3. import android.support.v7.app.ActionBarActivity;
  4. import android.os.Bundle;
  5. import android.support.v7.widget.DefaultItemAnimator;
  6. import android.support.v7.widget.LinearLayoutManager;
  7. import android.support.v7.widget.RecyclerView;
  8. import android.view.Menu;
  9. import android.view.MenuItem;
  10. import android.view.View;
  11. import android.widget.Toast;
  12.  
  13. import java.util.ArrayList;
  14. import java.util.List;
  15.  
  16. /**
  17. * @Class: ListLayoutActivity
  18. * @Description: RecycleView实现listview的功能
  19. * @author: lling(www.liuling123.com)
  20. * @Date: 2015/10/29
  21. */
  22. public class ListLayoutActivity extends ActionBarActivity {
  23.  
  24. private RecyclerView mRecyclerView;
  25. private ListAdapter mListAdapter;
  26. private List<String> mDatas;
  27.  
  28. @Override
  29. protected void onCreate(Bundle savedInstanceState) {
  30. super.onCreate(savedInstanceState);
  31. setContentView(R.layout.activity_list_layout);
  32. initData();
  33. mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
  34. mListAdapter = new ListAdapter(this, mDatas);
  35. mListAdapter.setOnItemClickListener(new ListAdapter.OnItemClickListener() {
  36. @Override
  37. public void onItemClick(View view, int position) {
  38. Toast.makeText(ListLayoutActivity.this, "Click" + mDatas.get(position), Toast.LENGTH_SHORT).show();
  39. }
  40.  
  41. @Override
  42. public void onItemLongClick(View view, int position) {
  43. mListAdapter.remove(position); //remove the item
  44. Toast.makeText(ListLayoutActivity.this, "LongClick" + mDatas.get(position), Toast.LENGTH_SHORT).show();
  45. }
  46. });
  47. mRecyclerView.setAdapter(mListAdapter);
  48. /**
  49. * 设置布局管理器,listview风格则设置为LinearLayoutManager
  50. * gridview风格则设置为GridLayoutManager
  51. * pu瀑布流风格的设置为StaggeredGridLayoutManager
  52. */
  53. mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
  54. // 设置item分
  55. mRecyclerView.addItemDecoration(new ListItemDecoration(this, LinearLayoutManager.VERTICAL));
  56. // 设置item动画
  57. mRecyclerView.setItemAnimator(new DefaultItemAnimator());
  58.  
  59. }
  60.  
  61. @Override
  62. public boolean onCreateOptionsMenu(Menu menu) {
  63. getMenuInflater().inflate(R.menu.menu_list_layout, menu);
  64. return true;
  65. }
  66.  
  67. @Override
  68. public boolean onOptionsItemSelected(MenuItem item) {
  69. switch (item.getItemId()) {
  70. case R.id.add_first:
  71. mListAdapter.add(0, "add first");
  72. break;
  73. case R.id.add_last:
  74. mListAdapter.add(mListAdapter.getItemCount(), "add last");
  75. break;
  76. case R.id.remove_first:
  77. String value = mListAdapter.remove(0);
  78. Toast.makeText(ListLayoutActivity.this, "remove:" + value, Toast.LENGTH_SHORT).show();
  79. break;
  80. case R.id.remove_last:
  81. String value1 = mListAdapter.remove(mListAdapter.getItemCount()-1);
  82. Toast.makeText(ListLayoutActivity.this, "remove:" + value1, Toast.LENGTH_SHORT).show();
  83. break;
  84. case R.id.horizontal:
  85. mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
  86. mRecyclerView.addItemDecoration(new ListItemDecoration(this, LinearLayoutManager.HORIZONTAL));
  87. break;
  88. case R.id.vertical:
  89. mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
  90. mRecyclerView.addItemDecoration(new ListItemDecoration(this, LinearLayoutManager.VERTICAL));
  91. break;
  92. }
  93. return super.onOptionsItemSelected(item);
  94. }
  95.  
  96. /* ==========This Part is not necessary========= */
  97.  
  98. /**
  99. * Create datas
  100. */
  101. protected void initData() {
  102. mDatas = new ArrayList<String>();
  103. for (int i = 0; i < 100; i++) {
  104. mDatas.add(String.valueOf(i));
  105. }
  106. }
  107.  
  108. /* ==========This Part is not necessary========= */
  109. }
 
activity布局:
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent" >
  5.  
  6. <android.support.v7.widget.RecyclerView
  7. android:id="@+id/recyclerview"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent" />
  10.  
  11. </RelativeLayout>
Adapter:
  1. package com.bbk.lling.recyclerview;
  2.  
  3. import android.annotation.SuppressLint;
  4. import android.content.Context;
  5. import android.support.v7.widget.RecyclerView;
  6. import android.util.Log;
  7. import android.view.LayoutInflater;
  8. import android.view.View;
  9. import android.view.ViewGroup;
  10. import android.widget.TextView;
  11.  
  12. import java.util.List;
  13.  
  14. /**
  15. * @Class: ListAdapter
  16. * @Description: 数据适配器
  17. * @author: lling(www.liuling123.com)
  18. * @Date: 2015/10/29
  19. */
  20. public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ItemViewHolder> {
  21.  
  22. private List<String> mDatas;
  23. private LayoutInflater mInflater;
  24. private OnItemClickListener mOnItemClickListener;
  25.  
  26. public ListAdapter(Context context, List<String> mDatas) {
  27. this.mDatas = mDatas;
  28. mInflater = LayoutInflater.from(context);
  29. }
  30.  
  31. @Override
  32. public int getItemCount() {
  33. return mDatas.size();
  34. }
  35.  
  36. @SuppressLint("NewApi")
  37. @Override
  38. public void onBindViewHolder(final ItemViewHolder itemViewHolder, final int i) {
  39. itemViewHolder.mTextView.setText(mDatas.get(i));
  40. if(mOnItemClickListener != null) {
  41. /**
  42. * 这里加了判断,itemViewHolder.itemView.hasOnClickListeners()
  43. * 目的是减少对象的创建,如果已经为view设置了click监听事件,就不用重复设置了
  44. * 不然每次调用onBindViewHolder方法,都会创建两个监听事件对象,增加了内存的开销
  45. */
  46. if(!itemViewHolder.itemView.hasOnClickListeners()) {
  47. Log.e("ListAdapter", "setOnClickListener");
  48. itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
  49. @Override
  50. public void onClick(View v) {
  51. int pos = itemViewHolder.getPosition();
  52. mOnItemClickListener.onItemClick(v, pos);
  53. }
  54. });
  55. itemViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
  56. @Override
  57. public boolean onLongClick(View v) {
  58. int pos = itemViewHolder.getPosition();
  59. mOnItemClickListener.onItemLongClick(v, pos);
  60. return true;
  61. }
  62. });
  63. }
  64. }
  65. }
  66.  
  67. @Override
  68. public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
  69. /**
  70. * 使用RecyclerView,ViewHolder是可以复用的。这根使用ListView的VIewHolder复用是一样的
  71. * ViewHolder创建的个数好像是可见item的个数+3
  72. */
  73. Log.e("ListAdapter", "onCreateViewHolder");
  74. ItemViewHolder holder = new ItemViewHolder(mInflater.inflate(
  75. R.layout.item_layout, viewGroup, false));
  76. return holder;
  77. }
  78.  
  79. /**
  80. * 向指定位置添加元素
  81. * @param position
  82. * @param value
  83. */
  84. public void add(int position, String value) {
  85. if(position > mDatas.size()) {
  86. position = mDatas.size();
  87. }
  88. if(position < 0) {
  89. position = 0;
  90. }
  91. mDatas.add(position, value);
  92. /**
  93. * 使用notifyItemInserted/notifyItemRemoved会有动画效果
  94. * 而使用notifyDataSetChanged()则没有
  95. */
  96. notifyItemInserted(position);
  97. }
  98.  
  99. /**
  100. * 移除指定位置元素
  101. * @param position
  102. * @return
  103. */
  104. public String remove(int position) {
  105. if(position > mDatas.size()-1) {
  106. return null;
  107. }
  108. String value = mDatas.remove(position);
  109. notifyItemRemoved(position);
  110. return value;
  111. }
  112.  
  113. public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
  114. this.mOnItemClickListener = mOnItemClickListener;
  115. }
  116.  
  117. /**
  118. * 处理item的点击事件和长按事件
  119. */
  120. interface OnItemClickListener {
  121. public void onItemClick(View view, int position);
  122. public void onItemLongClick(View view, int position);
  123. }
  124.  
  125. class ItemViewHolder extends RecyclerView.ViewHolder {
  126.  
  127. private TextView mTextView;
  128.  
  129. public ItemViewHolder(View itemView) {
  130. super(itemView);
  131. mTextView = (TextView) itemView.findViewById(R.id.textview);
  132. }
  133. }
  134.  
  135. }
        这里值得注意的是,RecyclerView并没有提供setOnItemClickListener方法来设置item的点击事件,所以这里我们自己来实现item的点击事件,这点很坑爹有木有?没有就自己设置呗!上面代码121-124定义了一个点击接口。然后给Adapter设置定义的接口对象,然后在onBindViewHolder中为每个holder设置点击事件就行了。但是有一点得注意,因为只要滑动RecyclerView,onBindViewHolder就会不停的调用,如果不加判断的话,则会不停的创建新的点击事件对象,浪费内存,所以在设置点击事件之前需要判断一下是否已经设置过了(如上面代码46行),如果设置过了就不需要创建了。
 
item的布局:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <TextView
  6. android:id="@+id/textview"
  7. android:layout_width="wrap_content"
  8. android:layout_height="48dp"
  9. android:minWidth="48dp"
  10. android:gravity="center"
  11. android:layout_centerInParent="true"
  12. android:text="XXX"/>
  13. </RelativeLayout>
item分割线:
  1. package com.bbk.lling.recyclerview;
  2.  
  3. import android.content.Context;
  4. import android.graphics.Canvas;
  5. import android.graphics.Rect;
  6. import android.graphics.drawable.Drawable;
  7. import android.support.v7.widget.LinearLayoutManager;
  8. import android.support.v7.widget.RecyclerView;
  9. import android.view.View;
  10.  
  11. /**
  12. * @Class: ListItemDecoration
  13. * @Description: listview的item分割线
  14. * @author: lling(www.liuling123.com)
  15. * @Date: 2015/10/29
  16. */
  17. public class ListItemDecoration extends RecyclerView.ItemDecoration {
  18.  
  19. private Drawable mDrawable;
  20.  
  21. private final static int DEFAULT_ORENTATION = LinearLayoutManager.VERTICAL;
  22.  
  23. private int mOrientation;
  24.  
  25. public ListItemDecoration(Context context, int orientation) {
  26. if(orientation != LinearLayoutManager.HORIZONTAL && orientation != LinearLayoutManager.VERTICAL) {
  27. this.mOrientation = DEFAULT_ORENTATION;
  28. } else {
  29. this.mOrientation = orientation;
  30. }
  31. mDrawable = context.getResources().getDrawable(R.drawable.divider);
  32. }
  33.  
  34. @Override
  35. public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
  36. if(mOrientation == LinearLayoutManager.HORIZONTAL) {
  37. drawHorizontal(c, parent);
  38. } else {
  39. drawVertical(c, parent);
  40. }
  41. }
  42.  
  43. private void drawHorizontal(Canvas c, RecyclerView parent) {
  44. int top = parent.getPaddingTop();
  45. int bottom = parent.getHeight() - parent.getPaddingBottom();
  46.  
  47. int childCount = parent.getChildCount();
  48. for (int i = 0; i < childCount; i++) {
  49. View child = parent.getChildAt(i);
  50. RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
  51. .getLayoutParams();
  52. int left = child.getRight() + params.rightMargin;
  53. int right = left + mDrawable.getIntrinsicHeight();
  54. mDrawable.setBounds(left, top, right, bottom);
  55. mDrawable.draw(c);
  56. }
  57. }
  58.  
  59. private void drawVertical(Canvas c, RecyclerView parent) {
  60. int left = parent.getPaddingLeft();
  61. int right = parent.getWidth() - parent.getPaddingRight();
  62.  
  63. int childCount = parent.getChildCount();
  64. for (int i = 0; i < childCount; i++) {
  65. View child = parent.getChildAt(i);
  66. android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
  67. RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
  68. .getLayoutParams();
  69. int top = child.getBottom() + params.bottomMargin;
  70. int bottom = top + mDrawable.getIntrinsicHeight();
  71. mDrawable.setBounds(left, top, right, bottom);
  72. mDrawable.draw(c);
  73. }
  74. }
  75.  
  76. @Override
  77. public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
  78. super.getItemOffsets(outRect, view, parent, state);
  79. }
  80. }
divider.xml:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
  3. <size android:height="1dp" android:width="1dp"/>
  4. <!--<solid android:color="#e0e0e0"/>-->
  5. <solid android:color="#ff0000"/>
  6. </shape>
 
好了,ListView的效果已经实现了,看下效果图
 
 
RecyclerView实现GridView以及瀑布流效果的代码这里就不贴出来了,demo源码里面有,需要的可以下载看看。
 
 

RecyclerView的使用的更多相关文章

  1. RecyclerView使用大全

    RecylerView介绍 RecylerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字recyler ...

  2. 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载

    title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...

  3. 安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路

    针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest ...

  4. Android Studio开发RecyclerView遇到的各种问题以及解决(二)

    开发RecyclerView时候需要导入别人的例子,我的是从github导入的,下载下github的压缩包之后解压看你要导入的文件是priject还是Module.(一般有app文件夹的大部分是pro ...

  5. Android Studio开发RecyclerView遇到的各种问题以及解决(一)

    以前一直在用ListView,,,最近才看RecyclerView发现好强大.RecyclerView前提是Android版本在5.0以上,本人以前用的是eclipse只支持到4.4.索性就安装一个A ...

  6. Android的Kotlin秘方(II):RecyclerView 和 DiffUtil

    作者:Antonio Leiva 时间:Sep 12, 2016 原文链接:http://antonioleiva.com/recyclerview-diffutil-kotlin/ 如你所知,在[支 ...

  7. Android RecyclerView 实现支付宝首页效果

    Android RecyclerView 实现支付宝首页效果 [TOC] 虽然我本人不喜欢支付宝的,但是这个网格本身其实还是不错的,项目更新中更改了一个布局为网格模式,类似支付宝.(估计是产品抄袭的= ...

  8. Android开发学习之路-RecyclerView滑动删除和拖动排序

    Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...

  9. 打造android偷懒神器———RecyclerView的万能适配器

    转载请注明出处谢谢:http://www.cnblogs.com/liushilin/p/5720926.html 很不好意思让大家久等了,本来昨天就应该写这个的,无奈公司昨天任务比较紧,所以没能按时 ...

  10. 安卓v7支持包下的ListView替代品————RecyclerView

    RecyclerView这个控件也出来很久了,相信大家也学习的差不多了,如果还没学习的,或许我可以带领大家体验一把这个艺术般的控件. 项目已经同步至github:https://github.com/ ...

随机推荐

  1. 用sql从一张表更新数据到另外一张表(多表数据迁移)

    update TBL_1 A, TBL_2 B, TBL_3 Cset a.email=c.email_addrwhere a.user_id=b.user_id and b.un_id=c.un_i ...

  2. c# 调用分页(控制器端的)与时间的格式

    1.在操作的model中: 2.在控制器中: , command.PageSize);//将从数据库获取到的集合进行分页 var gridModel = new DataSourceResult { ...

  3. 实现毛玻璃模糊效果/DRNRealTimeBlur

    四种方法:1.美工出图  2.coreImage框架,高斯效果 3.ToolBar,覆盖在view上边 //1.添加图片 self.imageView.image = [UIImage imageNa ...

  4. 7.5 [bx+idata] 书中错误

    这节中的问题 7.1 有错误 题目和我自己的注释为: 用 Debug 查看内存,结果如下: 2000:1000 BE 00 06 00 00 00 ... 写出下面程序执行后,ax,bx,cx中的内容 ...

  5. CSS3中的Transition属性详解(贝赛尔曲线)

    transition语法: transition : [<'transition-property'> || <'transition-duration'> || <'t ...

  6. PHP程序员的技术成长规划(转)

    第一阶段:基础阶段(基础PHP程序员) 重点:把LNMP搞熟练(核心是安装配置基本操作) 目标:能够完成基本的LNMP系统安装,简单配置维护:能够做基本的简单系统的PHP开发:能够在PHP中型系统中支 ...

  7. OkHttp使用介绍

    版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/4001708.html 为什么需要一个HTTP库 Androi ...

  8. Print2flash在.NET(C#)中的使用,即文档在线预览

    office文档(word,excel,ppt)在线预览查看,有很多种方式,比如可以 1.调用weboffice组件,进行word预览,要求客户端安装word,仅适用IE, word2013, IE1 ...

  9. console.log 被重写覆盖以后如何恢复

    有时候一些项目中会使用类似如下的方式覆盖掉console对象: var console = {}; console.log = function(){}; console.info = functio ...

  10. Windows下安装MinGW,编译c/c++时出现cannot find -lpthread解决办法

    由于Mingw下没有带pthread库,所以在eclipse中设置多线程动态链接库,也不管用.需要自己下载, ftp://sourceware.org/pub/pthreads-win32/pthre ...