RecyclerView简介
来源:互联网 发布:梦里花落知多少三毛txt 编辑:程序博客网 时间:2024/05/17 03:09
转载请注明出处:http://blog.csdn.net/allen315410/article/details/40379159
万众瞩目的android最新5.0版本不久前已经正式发布了,对于我这样对新事物不感冒的人来说,自然也是会关注的,除了新的android5.0带来的新的UI设计和用户体验之外,最让android程序员感兴趣的是5.0版本的sdk和一大堆新的API。5.0据说是额外增加或者修改了5000个API,新增了一些新的组件,下面介绍的RecyclerView就是其中之一,有人说Google设计出的RecyclerView是为了替代一直常用的ListView的,所以既然如此,我们就没理由不看看这个“传说”中的RecyclerView是怎么使用的了。
RecyclerView简介
该RecyclerView widget是一种更先进的柔性版的ListView。这个小工具是一个容器,用于显示,能非常有效地维护了意见数量有限,滚动大的数据集。使用 RecyclerView当你拥有的数据的集合,它的元素在运行时改变基于用户行为和网络事件的小部件。
该RecyclerView类简化,提供显示和处理大数据集:
定位项目布局管理器
默认的动画为公用项的操作,例如删除或增加的项目
您还可以在自定义的布局管理器和动画的灵活性RecyclerView部件。
要使用RecyclerView小部件,你必须指定一个适配器和一个布局管理器。要创建一个适配器,扩展RecyclerView.Adapter类。实施的细节取决于你的数据集的具体情况和意见的类型。欲了解更多信息,请参见示例如下。
布局管理器 A的内部位置的项目意见RecyclerView,并确定何时再利用项目的看法不再对用户可见。重用(或回收)的图,布局管理器可能会问适配器与数据集不同的元素替换视图的内容。以这种方式回收的观点提高通过避免产生不必要的视图或执行昂贵性能findViewById()的查找。
RecyclerView提供这些内置的布局管理器:
LinearLayoutManager 显示在垂直或水平滚动列表项。
GridLayoutManager 显示在网格中的项目。
StaggeredGridLayoutManager 显示了交错网格项目。
要创建自定义布局管理器,扩展RecyclerView.LayoutManager类。
动画
动画的添加和删除项目中默认启用的RecyclerView。要自定义这些动画,延长 RecyclerView.ItemAnimator类,并使用RecyclerView.setItemAnimator() 方法。
以上内容来自Google官方文档的翻译,翻译比较生涩(我这英文水平,哎~~对付自己还行),下面直接上一个Demo看看具体的用法。
RecyclerView的用法
下面简单介绍制作一个小Demo,来一步步分析一下RecyclerView的用法。首先说明一下,RecyclerView是android.support.v7包下提供的组件,所以需要使用RecyclerView时,需要下载这个包,由于我已经将SDK升级到最新版本——API21,所以很容易在/sdk/extras/android/support/v7/appcompat/libs目录下找到这个jar以及源码,建议先升级sdk,再动手做!实在不想动手的下载的,点击博文下方的链接下载源码,源码里有RecyclerView的JAR包。
主界面布局,activity_main.xml
- <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="80dp"
- android:layout_centerVertical="true"
- android:background="@android:color/transparent"
- android:scrollbars="none" />
- </RelativeLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="120dp"
- android:layout_height="120dp" >
- <ImageView
- android:id="@+id/iv_image"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true"
- android:scaleType="centerCrop" />
- </RelativeLayout>
- public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
- private int[] mDataset; // 外面传入的数据
- public static class ViewHolder extends RecyclerView.ViewHolder {
- ImageView mImageView;
- // TODO Auto-generated method stub
- public ViewHolder(View v) {
- super(v);
- }
- }
- public MyAdapter(int[] mDataset) {
- this.mDataset = mDataset;
- }
- /**
- * 获取总的条目数量
- */
- @Override
- public int getItemCount() {
- // TODO Auto-generated method stub
- return mDataset.length;
- }
- /**
- * 创建ViewHolder
- */
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- // TODO Auto-generated method stub
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycleview, parent, false);
- ViewHolder holder = new ViewHolder(v);
- holder.mImageView = (ImageView) v.findViewById(R.id.iv_image);
- return holder;
- }
- /**
- * 将数据绑定到ViewHolder上
- */
- @Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- // TODO Auto-generated method stub
- holder.mImageView.setImageResource(mDataset[position]);
- }
- }
getItemCount() 获取Item的总数。
onCreateViewHolder(ViewGroup parent, int viewType) 创建ViewHolder。
onBindViewHolder(ViewHolder holder, int position) 将数据绑定到ViewHolder。
与ListView数据适配的对比
ListView里面有个getView()方法返回的View是Item的布局,那么这个RecyclerView的Item的布局在哪控制?其实是这样的,RecyclerView对ViewHolder也进行了一定的封装,我们创建的ViewHolder必须继承RecyclerView.ViewHolder,这个RecyclerView.ViewHolder的构造时必须传入一个View,这个View相当于我们ListView的getView()中的convertView (即:我们需要inflate的item布局需要传入)。
还有一点,ListView中convertView是复用的,在RecyclerView中,是把ViewHolder作为缓存的单位了,然后convertView作为ViewHolder的成员变量保持在ViewHolder中,也就是说,假设没有屏幕显示10个条目,则会创建10个ViewHolder缓存起来,每次复用的是ViewHolder,所以他把getView这个方法变为了onCreateViewHolder。
最后,就在Activity里使用这个RecyclerView,MainActivity.java- public class MainActivity extends Activity {
- /** RecyclerView对象 */
- private RecyclerView recyclerView;
- /** 图片资源 */
- private int[] mDataset;
- /** 数据适配器 */
- private MyAdapter mAdapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
- // 初始化图片数据
- mDataset = new int[] { R.drawable.a, R.drawable.b, //
- R.drawable.c, R.drawable.d, R.drawable.e, //
- R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.i };
- // 设置布局管理器
- LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
- linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
- recyclerView.setLayoutManager(linearLayoutManager);
- // 设置适配器
- mAdapter = new MyAdapter(mDataset);
- recyclerView.setAdapter(mAdapter);
- }
- }
在MainActivity使用RecyclerView如同使用ListView一样的简单,唯一不同的地方就是,需要给RecyclerView设置一个布局管理器,Google为我们提供了3种不同的布局管理(详细请看最上面的简介),这里我使用的LinearLayoutmanager,并且设置布局为水平显示。 好了,关于RecyclerView的基本用法讲完了,那个关于RecyclerView的另外两个布局管理器就暂时不说了,大同小异。下面是运行效果图
为RecyclerView设置事件回调
再使用RecyclerView组件时,发现了一个令人“痛心疾首”的问题:RecyclerView居然没有点击Item的事件监听设置,类似于ListView中起码有个setOnItemClickListener方法,用于监听Item点击并作出相应的逻辑处理。但是翻遍了RecyclerView的API,都没有发现这个或者类似这个功能的方法可用,这不得不说是个“悲剧”,还听说这个是为了替代ListView的,看来并不是这样的,请Google出来解释解释啊!
好了,Google应该近期是不会解释的了,但是我们得自己想办法解决这个问题,就是为RecyclerView添加一个回调函数,这个倒不难吧!实在无法领会的,可以看看我前面的那篇博文,Android自定义组件——仿ios滑动按钮,里面有一些相关的用法。下面是我在Adapter里添加的回调函数。
- public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
- private int[] mDataset; // 外面传入的数据
- /**
- * Item的回调接口
- *
- */
- public interface OnItemClickListener {
- void onItemClickListener(View view, int position);
- }
- private OnItemClickListener listener; // 点击Item的回调对象
- /**
- * 设置回调监听
- *
- * @param listener
- */
- public void setOnItemClickListener(OnItemClickListener listener) {
- this.listener = listener;
- }
- public static class ViewHolder extends RecyclerView.ViewHolder {
- ImageView mImageView;
- // TODO Auto-generated method stub
- public ViewHolder(View v) {
- super(v);
- }
- }
- public MyAdapter(int[] mDataset) {
- this.mDataset = mDataset;
- }
- /**
- * 获取总的条目数量
- */
- @Override
- public int getItemCount() {
- // TODO Auto-generated method stub
- return mDataset.length;
- }
- /**
- * 创建ViewHolder
- */
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- // TODO Auto-generated method stub
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycleview, parent, false);
- ViewHolder holder = new ViewHolder(v);
- holder.mImageView = (ImageView) v.findViewById(R.id.iv_image);
- return holder;
- }
- /**
- * 将数据绑定到ViewHolder上
- */
- @Override
- public void onBindViewHolder(ViewHolder holder, final int position) {
- // TODO Auto-generated method stub
- holder.mImageView.setImageResource(mDataset[position]);
- if (listener != null) {
- holder.mImageView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- listener.onItemClickListener(v, position);
- }
- });
- }
- }
- }
- mAdapter.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClickListener(View view, int position) {
- // TODO Auto-generated method stub
- Toast.makeText(MainActivity.this, position + "", Toast.LENGTH_SHORT).show();
- }
- });
源码请在这里下载
- RecyclerView简介
- RecyclerView入门简介
- RecyclerView简介和详细使用方法
- Android开发模板------RecyclerView简介
- RecyclerView的相关用法简介
- Android RecyclerView 使用简介(1)
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- RecyclerView
- 启动网页时候自动加载servlet如果不使用strus最常用的两种方式
- 在Activity和Service通讯中使用LocalBroadcastManage
- VS2010 常用快捷键
- Android APK反编译详解(附图)
- 课程实训(猜猜看游戏)进度二
- RecyclerView简介
- 字串问题
- 数据结构链表的操作集合(建立,遍历,插入,删除,排序,长度,空判断等)
- Android自定义一个简单的动画加载页面
- python 单下划线/双下划线使用总结
- 有了Java6,还需要Axis2、XFire、CXF吗?
- XSS攻击及防御
- JavaScript 小技巧
- Xcode插件