什么是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就可以了。
 /**
* 设置Adapter
*/
mRecyclerView.setAdapter(mListAdapter);
/**
* 设置布局管理器
*/
mRecyclerView.setLayoutManager(linearLayoutManager);
/**
* 设置item分割线
*/
mRecyclerView.addItemDecoration(itemDecoration);
/**
* 设置item动画
*/
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        使用RecyclerView,基本上要上面四步。相比ListView只需设置Adapter而言,RecyclerView的使用看起来似乎要复杂一些。但是它的可定制性更高了,你可以自己定制自己的分割线样式或者是item的的动画。
        下面我们看下如何使用RecyclerView简单实现ListView的效果。
activity:
 package com.bbk.lling.recyclerview;

 import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast; import java.util.ArrayList;
import java.util.List; /**
* @Class: ListLayoutActivity
* @Description: RecycleView实现listview的功能
* @author: lling(www.liuling123.com)
* @Date: 2015/10/29
*/
public class ListLayoutActivity extends ActionBarActivity { private RecyclerView mRecyclerView;
private ListAdapter mListAdapter;
private List<String> mDatas; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_layout);
initData();
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mListAdapter = new ListAdapter(this, mDatas);
mListAdapter.setOnItemClickListener(new ListAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(ListLayoutActivity.this, "Click" + mDatas.get(position), Toast.LENGTH_SHORT).show();
} @Override
public void onItemLongClick(View view, int position) {
mListAdapter.remove(position); //remove the item
Toast.makeText(ListLayoutActivity.this, "LongClick" + mDatas.get(position), Toast.LENGTH_SHORT).show();
}
});
mRecyclerView.setAdapter(mListAdapter);
/**
* 设置布局管理器,listview风格则设置为LinearLayoutManager
* gridview风格则设置为GridLayoutManager
* pu瀑布流风格的设置为StaggeredGridLayoutManager
*/
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
// 设置item分
mRecyclerView.addItemDecoration(new ListItemDecoration(this, LinearLayoutManager.VERTICAL));
// 设置item动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator()); } @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_list_layout, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_first:
mListAdapter.add(0, "add first");
break;
case R.id.add_last:
mListAdapter.add(mListAdapter.getItemCount(), "add last");
break;
case R.id.remove_first:
String value = mListAdapter.remove(0);
Toast.makeText(ListLayoutActivity.this, "remove:" + value, Toast.LENGTH_SHORT).show();
break;
case R.id.remove_last:
String value1 = mListAdapter.remove(mListAdapter.getItemCount()-1);
Toast.makeText(ListLayoutActivity.this, "remove:" + value1, Toast.LENGTH_SHORT).show();
break;
case R.id.horizontal:
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
mRecyclerView.addItemDecoration(new ListItemDecoration(this, LinearLayoutManager.HORIZONTAL));
break;
case R.id.vertical:
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.addItemDecoration(new ListItemDecoration(this, LinearLayoutManager.VERTICAL));
break;
}
return super.onOptionsItemSelected(item);
} /* ==========This Part is not necessary========= */ /**
* Create datas
*/
protected void initData() {
mDatas = new ArrayList<String>();
for (int i = 0; i < 100; i++) {
mDatas.add(String.valueOf(i));
}
} /* ==========This Part is not necessary========= */
}
 
activity布局:
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" > <android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" /> </RelativeLayout>
Adapter:
 package com.bbk.lling.recyclerview;

 import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; import java.util.List; /**
* @Class: ListAdapter
* @Description: 数据适配器
* @author: lling(www.liuling123.com)
* @Date: 2015/10/29
*/
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ItemViewHolder> { private List<String> mDatas;
private LayoutInflater mInflater;
private OnItemClickListener mOnItemClickListener; public ListAdapter(Context context, List<String> mDatas) {
this.mDatas = mDatas;
mInflater = LayoutInflater.from(context);
} @Override
public int getItemCount() {
return mDatas.size();
} @SuppressLint("NewApi")
@Override
public void onBindViewHolder(final ItemViewHolder itemViewHolder, final int i) {
itemViewHolder.mTextView.setText(mDatas.get(i));
if(mOnItemClickListener != null) {
/**
* 这里加了判断,itemViewHolder.itemView.hasOnClickListeners()
* 目的是减少对象的创建,如果已经为view设置了click监听事件,就不用重复设置了
* 不然每次调用onBindViewHolder方法,都会创建两个监听事件对象,增加了内存的开销
*/
if(!itemViewHolder.itemView.hasOnClickListeners()) {
Log.e("ListAdapter", "setOnClickListener");
itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = itemViewHolder.getPosition();
mOnItemClickListener.onItemClick(v, pos);
}
});
itemViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos = itemViewHolder.getPosition();
mOnItemClickListener.onItemLongClick(v, pos);
return true;
}
});
}
}
} @Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
/**
* 使用RecyclerView,ViewHolder是可以复用的。这根使用ListView的VIewHolder复用是一样的
* ViewHolder创建的个数好像是可见item的个数+3
*/
Log.e("ListAdapter", "onCreateViewHolder");
ItemViewHolder holder = new ItemViewHolder(mInflater.inflate(
R.layout.item_layout, viewGroup, false));
return holder;
} /**
* 向指定位置添加元素
* @param position
* @param value
*/
public void add(int position, String value) {
if(position > mDatas.size()) {
position = mDatas.size();
}
if(position < 0) {
position = 0;
}
mDatas.add(position, value);
/**
* 使用notifyItemInserted/notifyItemRemoved会有动画效果
* 而使用notifyDataSetChanged()则没有
*/
notifyItemInserted(position);
} /**
* 移除指定位置元素
* @param position
* @return
*/
public String remove(int position) {
if(position > mDatas.size()-1) {
return null;
}
String value = mDatas.remove(position);
notifyItemRemoved(position);
return value;
} public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
} /**
* 处理item的点击事件和长按事件
*/
interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onItemLongClick(View view, int position);
} class ItemViewHolder extends RecyclerView.ViewHolder { private TextView mTextView; public ItemViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.textview);
}
} }
        这里值得注意的是,RecyclerView并没有提供setOnItemClickListener方法来设置item的点击事件,所以这里我们自己来实现item的点击事件,这点很坑爹有木有?没有就自己设置呗!上面代码121-124定义了一个点击接口。然后给Adapter设置定义的接口对象,然后在onBindViewHolder中为每个holder设置点击事件就行了。但是有一点得注意,因为只要滑动RecyclerView,onBindViewHolder就会不停的调用,如果不加判断的话,则会不停的创建新的点击事件对象,浪费内存,所以在设置点击事件之前需要判断一下是否已经设置过了(如上面代码46行),如果设置过了就不需要创建了。
 
item的布局:
 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:minWidth="48dp"
android:gravity="center"
android:layout_centerInParent="true"
android:text="XXX"/>
</RelativeLayout>
item分割线:
 package com.bbk.lling.recyclerview;

 import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View; /**
* @Class: ListItemDecoration
* @Description: listview的item分割线
* @author: lling(www.liuling123.com)
* @Date: 2015/10/29
*/
public class ListItemDecoration extends RecyclerView.ItemDecoration { private Drawable mDrawable; private final static int DEFAULT_ORENTATION = LinearLayoutManager.VERTICAL; private int mOrientation; public ListItemDecoration(Context context, int orientation) {
if(orientation != LinearLayoutManager.HORIZONTAL && orientation != LinearLayoutManager.VERTICAL) {
this.mOrientation = DEFAULT_ORENTATION;
} else {
this.mOrientation = orientation;
}
mDrawable = context.getResources().getDrawable(R.drawable.divider);
} @Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if(mOrientation == LinearLayoutManager.HORIZONTAL) {
drawHorizontal(c, parent);
} else {
drawVertical(c, parent);
}
} private void drawHorizontal(Canvas c, RecyclerView parent) {
int top = parent.getPaddingTop();
int bottom = parent.getHeight() - parent.getPaddingBottom(); int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
int left = child.getRight() + params.rightMargin;
int right = left + mDrawable.getIntrinsicHeight();
mDrawable.setBounds(left, top, right, bottom);
mDrawable.draw(c);
}
} private void drawVertical(Canvas c, RecyclerView parent) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDrawable.getIntrinsicHeight();
mDrawable.setBounds(left, top, right, bottom);
mDrawable.draw(c);
}
} @Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
}
}
divider.xml:
 <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<size android:height="1dp" android:width="1dp"/>
<!--<solid android:color="#e0e0e0"/>-->
<solid android:color="#ff0000"/>
</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. 统计学习方法笔记 Logistic regression

    logistic distribution 设X是连续随机变量,X服从逻辑斯谛分布是指X具有下列分布函数和密度函数: 式中,μ为位置参数,γ>0为形状参数. 密度函数是脉冲函数 分布函数是一条S ...

  2. emacs windows 下配置

    一般windows的emacs是一个压缩包,解压一下,即可.主程序在bin文件夹下.需要设置一下emacs的home路径, 打开注册表,创建HKEY_LOCAL_MACHINE/SOFTWARE/GN ...

  3. AutoResetEvent信号锁 waitone set 执行一次线程退出 挺不爽的地方

    下边有个 循环调用线程写奇偶数的程序 class TheadTest { //定义一个Stream对象接收打开文件 private FileStream st; //构造方法 public Thead ...

  4. Jquery点击发送按钮后,按钮文本倒计时

    1.html代码 <input type="number" id="mobileNo" placeholder="请输入手机号" /& ...

  5. linux系统基础网络配置

    1.修改主机名 临时方法: 退出当前shell重新登录即可生效.此法只能临时修改生效.重启系统后失效. 提示:很多人使用hostname主机名来修改,其实这个只是作为暂时的.重启后将恢复到配置前的主机 ...

  6. 记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?)

    记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的, ...

  7. 用c#开发微信 (22) 微信商城 - 微信支付 (c#源码)

    微信支付有几种支付模式:刷卡支付,扫码支付,公众号支付,APP支付.本文介绍用于在微信商城里的公众号支付. 1. 效果图 在商城里购买商品后,到支付页面: 点击上面的确认支付,转到下面微信支付页面: ...

  8. python脚本实现集群检测和管理

    python脚本实现集群检测和管理 场景是这样的:一个生产机房,会有很多的测试机器和生产机器(也就是30台左右吧),由于管理较为混乱导致了哪台机器有人用.哪台机器没人用都不清楚,从而产生了一个想法-- ...

  9. Nginx学习笔记(八) Nginx进程启动分析

    Nginx进程启动分析 worker子进程的执行循环的函数是ngx_worker_process_cycle (src/os/unix/ngx_process_cycle.c). 其中,捕获事件.分发 ...

  10. 每周一道数据结构(四)A*算法&博弈树α-β剪枝

    A*算法/博弈树 前阵子考试学了A*算法.博弈树和回溯,自己真是愚蠢至极,根本没就搞明白这些,所以对于这些算法问道的话就不能说清楚,也记不住,所以才有了这篇笔记.在这里感谢面试我的那位工程师~~ A* ...