Android RecyclerView总结

来源:互联网 发布:php asp jsp 区别 编辑:程序博客网 时间:2024/04/29 18:41

Android RecyclerView总结

       从Android 5.0(API等级21,2014年6月26日更新)开始,谷歌公司推出了RecyclerView控件.目的是用来替代ListView。但是RecyclerView的用法有点不一样,很多人还没有知道怎么去用。
       网上下载的关于Android的API基本都是没有关于RecyclerView介绍的,但是有一个好消息就是,上一年年末,google网站已经对中国正式开放了(不过是全英文的,最好下载一个网页翻译工具查看)。
Google网址:https://developer.android.google.cn
关于RecyclerView的API介绍的链接:
https://developer.android.google.cn/reference/android/support/v7/widget/RecyclerView.html

一.关于RecyclerView的基础知识

(一)RecyclerView是什么?

       Recycler是回收的意思,那么RecyclerView是有自动回收View对象的功能的。
       RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字Recyclerview即回收view也可以看出。看到这也许有人会问,不是已经有ListView了吗,为什么还要RecyclerView呢?这就牵扯到第二个问题了。

(二)RecyclerView的优点是什么?

       根据官方的介绍RecyclerView是ListView的升级版,既然如此那RecyclerView必然有它的优点,现就RecylerView相对于ListView的优点罗列如下:
>
(1)RecyclerView封装了viewholder的回收复用,也就是说RecyclerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。
(2) 提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecyclerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还StaggeredGridLayoutManager等),也就是说RecyclerView不再拘泥于ListView的线性展示方式,它也可以实现GridView的效果等多种效果。你想控制Item的分隔线,可以通过继承RecyclerView的ItemDecoration这个类,然后针对自己的业务需求去抒写代码。
(3)可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecyclerView有其自己默认的实现。

RecyckerView程序主要代码:

//实例化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());可以看到对RecylerView的设置过程,比ListView要复杂一些,虽然代码抒写上有点复杂,但它的扩展性是极高的。

(三)RecyclerView布局管理器

1.线性布局管理器

//使用线性布局管理器,这是最简单的线性布局管理器

 LayoutManager layout = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(layout);

效果(和ListView一样):
x1

//第二种线性布局管理器的构造方法:

LinearLayoutManager(context, orientation, reverseLayout)第一个参数是Context,第二个参数是布局方向,其值可以取LinearLayoutManager.HORIZONTAL 水平LinearLayoutManager.VERTICAL 垂直第三个参数是是否逆向布局如果设置为true,则反向开始布局。现在我们将布局设置为水平,并逆向布局,使用下面的代码LayoutManager layout = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,true);

效果:
x2

2.网格布局管理器

//使用表格布局管理器,这是最简单的表格布局管理器

LayoutManager layout=new GridLayoutManager(this,2);

//跟线性布局一样,网格布局还有一个构造函数,其意义同线性布局,这里,我们不适用逆向布局,设置2列,垂直,代码如下:

LayoutManager layout=new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);

效果:
w

3.流式布局管理器
//该类只有一个构造函数,一个是列数或者行数,另一个是布局方向

LayoutManager layout=new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);

效果:
l
可以看到流式布局,每个Item的高度是可以不一样的,而对比网格布局它的每个Item的高度是一样的。

(四)紧接着来看看它的Adapter的写法

       RecyclerView的Adapter与ListView的Adapter还是有点区别的,RecyclerView.Adapter,需要实现3个方法:

(1) onCreateViewHolder()

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

(2) onBindViewHolder()

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

(3) getItemCount()

       这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。接下来通过几个小的实例帮助大家更深入的了解RecyclerView的用法。

(4)创建Adapter的基本代码:

 /** * RecyclerViewAdaper适配器的创建 * 针对的数据类型Bean肯定是不同的,那么这里肯定要引入泛型代表我们的Bean,内部通过一个List代表我们的数据, */public  class MyAdapter<T> extends RecyclerView.Adapter {    private String[] mDataset;//数据源    private Context mContexts;//上下文    private  int mLayoutID;//显示的条目的布局    //构造方法,传入上下文和数据源,条目的布局ID    public MyAdapter(Context contexts,int layoutID,String[]myDataset) {        mContexts=contexts;        mDataset = myDataset;        mLayoutID=layoutID;    }    //第一个重要的方法,创建ViewHolder对象,也是这三个方法中最难理解的一个    //这个方法需要创建一个ViewHolder类(继承RecyclerView.ViewHolde)    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        //根据布局ID创建View对象        View v = LayoutInflater.from(parent.getContext()).inflate(mLayoutID, parent, false);        return new MyViewHolder(v);    }    //第二个重要的方法,绑定ViewHolder对象,这里可以避免多次的findViewById    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        MyViewHolder  myHolder=(MyViewHolder)holder;//转换对象,成子类的对象,才能设置子类的属性        myHolder.image.setImageResource(R.mipmap.ic_launcher);//设置图片        myHolder.text.setText("---"+mDataset[position]);//給文本设置内容        myHolder.itemView.setTag(myHolder);//设置Tag    }    //第三个重要的方法,返回显示的Item 的数量,这个也是最容易理解的!    @Override    public int getItemCount() {        return mDataset.length;    }    //创建一个自己的ViewHolder类继承自RecyclerView.ViewHolder    //要在里面实现一个次控件的创建,避免多次的创建或findViewById    public static class MyViewHolder extends RecyclerView.ViewHolder  {        private ImageView image;        private TextView text;        public MyViewHolder(View itemView) {            super(itemView);             image = (ImageView) itemView.findViewById(R.id.imageView);            text = (TextView) itemView.findViewById(R.id.textView);        }    }}

如果Item只有一个String数据,那么设置Adapter语句如下:

//创建,设置Adapter,//这里要传入上下文,Iten条目的布局ID,数据源三个元素,// 这里还使用的泛型的写法(主要是针对数据源的扩展,因为很多程序中数据源都是Bean对象,//那么这个泛型可以改成Bena类)MyAdapter adapter=new MyAdapter<String>(this,R.layout.item,mDataset);recyclerView.setAdapter(adapter);

二.简单显示RecyclerView的示例程序

       我刚接触RecyclerView时,也是不知道怎么用,网上有很多都是片段,我看起来都乱,有些代码是可以显示的,但是它们经过了太多的封装或变换,也是比较乱,很不利于基础的学习。
       其实RecyclerView的简单显示需要四个元素,数据源、RecyclerView组件,Adapter适配器,布局管理器,前三个和ListView的显示不是差不多吗!但是这里RecyclerView的Adapter是比较难一点的,你需要对比ListView的Adapter,这样就更好理解。
ListView的显示:http://blog.csdn.net/wenzhi20102321/article/details/53443060
这里是在想当于ListView,简单显示效果:
R1
RecyclerView显示的代码:

(一)添加类库依赖

compile 'com.android.support:recyclerview-v7:24.0.+'

如图:
y1

(二)activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?><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"    tools:context="com.example.recyclerviewdemo.MainActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/recyclerView"        android:layout_width="match_parent"        android:layout_height="match_parent"        /></RelativeLayout>

(三)Item的布局文件item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal" android:layout_width="match_parent"    android:layout_height="50dp"><ImageView    android:layout_width="50dp"    android:layout_height="50dp"    android:id="@+id/imageView"    />    <TextView        android:layout_gravity="center"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/textView"        /></LinearLayout>

(四)关键Adapter类的创建

package com.example.recyclerviewdemo;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.ImageView;import android.widget.LinearLayout;import android.widget.TextView;/** * RecyclerViewAdaper适配器的创建 * 针对的数据类型Bean肯定是不同的,那么这里可以要引入泛型代表我们的Bean的数据源的数据, * 但是本题是可以不使用泛型的,因为数据源的类型是String类型 */public  class MyAdapter<T> extends RecyclerView.Adapter {    private String[] mDataset;//数据源    private Context mContexts;//上下文    private  int mLayoutID;//显示的条目的布局    //构造方法,传入上下文和数据源,条目的布局ID    public MyAdapter(Context contexts,int layoutID,String[]myDataset) {        mContexts=contexts;        mDataset = myDataset;        mLayoutID=layoutID;    }    //第一个重要的方法,创建ViewHolder对象,也是这三个方法中最难理解的一个    //这个方法需要创建一个ViewHolder类(继承RecyclerView.ViewHolde)    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        //根据布局ID创建View对象        View v = LayoutInflater.from(parent.getContext()).inflate(mLayoutID, parent, false);        return new MyViewHolder(v);    }    //第二个重要的方法,绑定ViewHolder对象,这里可以避免多次的findViewById    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        MyViewHolder  myHolder=(MyViewHolder)holder;//转换对象,成子类的对象,才能设置子类的属性        myHolder.image.setImageResource(R.mipmap.ic_launcher);//设置图片        myHolder.text.setText("---"+mDataset[position]);//給文本设置内容        myHolder.itemView.setTag(myHolder);//设置Tag    }    //第三个重要的方法,返回显示的Item 的数量,这个也是最容易理解的!    @Override    public int getItemCount() {        return mDataset.length;    }    //创建一个自己的ViewHolder类继承自RecyclerView.ViewHolder    //要在里面实现一个次控件的创建,避免多次的创建或findViewById    public static class MyViewHolder extends RecyclerView.ViewHolder  {        private ImageView image;        private TextView text;        public MyViewHolder(View itemView) {            super(itemView);             image = (ImageView) itemView.findViewById(R.id.imageView);            text = (TextView) itemView.findViewById(R.id.textView);        }    }}

(五)主方法的类的创建

package com.example.recyclerviewdemo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.DefaultItemAnimator;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.OrientationHelper;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;public class MainActivity extends AppCompatActivity {   //定义RecyclerView组件    RecyclerView recyclerView;    private RecyclerView.LayoutManager layoutManager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);        //创建布局管理器(这里是线性)        LinearLayoutManager layoutManager = new LinearLayoutManager(this );        //设置布局管理器        recyclerView.setLayoutManager(layoutManager);        //设置为垂直布局,这也是默认的        layoutManager.setOrientation(OrientationHelper. VERTICAL);        //设置默认的条目的显示的效果,当然也是可以自定义的        recyclerView.setItemAnimator(new DefaultItemAnimator());       //设置数据源         String[] mDataset=new String[50];        for (int i = 0; i < mDataset.length; i++) {            mDataset[i]="行"+i;        }        //创建,设置Adapter,        //这里要传入上下文,Iten条目的布局ID,数据源三个元素,        // 这里还使用的泛型的写法(主要是针对数据源的扩展,因为很多程序中数据源都是Bean对象,那么这个泛型可以改成Bena类)        MyAdapter adapter=new MyAdapter<String>(this,R.layout.item,mDataset);        recyclerView.setAdapter(adapter);    }}

       到这里,Recycler就能显示出来了,有点难理解的就是Adapter类的创建,其他部分都是比较容易理解的!
程序运行后的效果:
ww

三.RecyclerView显示后的进阶学习

这里RecyclerView很多事件的处理都是在Adapter类中或使用Adapter对象进行的!

(一)点击事件或长按事件的设置

       这个跟ListView的设置是有很大的区别
       如果上面一个程序要給右边的文本添加点击的监听事件,那么可以在视图绑定的方法onBindViewHolder中设置点击事件或长按事件,当然也是可以自己写回调接口。
示例代码:

//第二个重要的方法,绑定ViewHolder对象,这里可以避免多次的findViewById@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {    MyViewHolder  myHolder=(MyViewHolder)holder;//转换对象,成子类的对象,才能设置子类的属性    myHolder.image.setImageResource(R.mipmap.ic_launcher);//设置图片    myHolder.text.setText("---"+mDataset[position]);//給文本设置内容    //給文本设置点击事件    myHolder.text.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Toast.makeText(mContexts,"你点中了:"+mDataset[position],Toast.LENGTH_SHORT).show();        }    });    //給文本设置长按事件    myHolder.text.setOnLongClickListener(new View.OnLongClickListener() {        @Override        public boolean onLongClick(View v) {            Toast.makeText(mContexts,"你长按了:"+mDataset[position],Toast.LENGTH_SHORT).show();            return true;//表示消化,不再重复触发点击        }    });    myHolder.itemView.setTag(myHolder);//设置Tag}

(二)Adapter对象的一些方法

        public final void notifyDataSetChanged()        public final void notifyItemChanged(int position)        public final void notifyItemRangeChanged(int positionStart, int itemCount)        public final void notifyItemInserted(int position)         public final void notifyItemMoved(int fromPosition, int toPosition)        public final void notifyItemRangeInserted(int positionStart, int itemCount)        public final void notifyItemRemoved(int position)        public final void notifyItemRangeRemoved(int positionStart, int itemCount) 基本上看到方法的名字就知道这个方法是干嘛的了(都是刷新适配器),但是还是要解释一下,帮助大家理解。除了第一个是全部数据刷新,其他都是局部刷新!

1.notifyDataSetChanged()方法

       没什么好讲的,跟以前一样,是刷新适配器所有的数据的意思。

2.notifyItemChanged(int position)方法,刷新Adapter某一条Item的数据!

       第position个条目数据发生了改变,那调用这个方法,就会回调对应position的onBindViewHolder()方法了,当然,因为ViewHolder是复用的,所以如果position在当前屏幕以外,也就不会回调了,因为没有意义,下次position滚动会当前屏幕以内的时候同样会调用onBindViewHolder()方法刷新数据了。其他的方法也是同样的道理。

3.notifyItemRangeChanged(int positionStart, int itemCount),刷新Adapter某一条或多条Item的数据!

       顾名思义,可以刷新从positionStart开始itemCount数量的item了(这里的刷新指回调onBindViewHolder()方法)。

4.notifyItemInserted(int position),在第position位置被插入了一条数据的时候可以使用这个方法刷新,注意这个方法调用后会有插入的动画,这个动画可以使用默认的,也可以自己定义。

5.notifyItemMoved(int fromPosition, int toPosition),从fromPosition移动到toPosition为止的时候可以使用这个方法显示动画

6.notifyItemRangeInserted(int positionStart, int itemCount),显然是批量添加后显示动画。

7.notifyItemRemoved(int position),第position个被删除,同样会有动画。

8.notifyItemRangeRemoved(int positionStart, int itemCount),批量删除后刷新。

这里很有必要总结一下上面的方法,其中第一个到第三个方法都是刷新适配器的方法,而后面的方法是在相关操作时显示动画效果的设置,如果不理解,可以看后面的增删改查的操作的代码。

(三)RecyclerView条目的增删改查操作

1.增加

在position为2的位置添加一个条目数据,代码:adapter.notifyItemInserted(2);dataList.add(2, “newDataString”); adapter.notifyItemRangeChanged(2, adapter.getItemCount());

代码解释:
第一行代码:表示在position为2的位置,插入一条数据,这个时候动画开始执行。如果没有这句话时没有动画效果的。
第二行代码:表示在数据源中position为2的位置新增一条数据(其实这个才是真正的新增数据啦)。
第三行代码:刷新position为2以后的所有Item的数据视图。
为什么要刷新position为2以后的数据呢?因为,在position为2的位置插入了一条数据后,新数据的position变成了2,那原来的position为2的应该变成了3,3的应该变成了4,所以2以后的所有数据的position都发生了改变,所以需要把position2以后的数据都要刷新。理论上是这样,但是实际上刷新的数量只有在屏幕上显示的position为2以后的数据而已。如果这里使用notifyDataSetChanged()来刷新屏幕上显示的所有item可以吗?结果不会出错,但是会有一个问题,前面调用了notifyItemInserted()方法后会在执行动画,如果你调用notifyDataSetChanged()刷新屏幕上显示的所有item的话,必然也会刷新当前正在执行动画的那个item,这样导致的结果是,前面的动画还没执行完,它马上又被刷新了,动画就看不见了。所以只要刷新2以后的item就可以了。

2.删除

删除position为2位置的条目的一条数据的代码:adapter.notifyItemRemoved(position);dataList.remove(position);adapter.notifyItemRangeChanged(position, adapter.getItemCount());

3.修改

修改position为2位置的条目数据代码:mDataset.set(2,"newDataString"+num++);adapter.notifyItemChanged(2);

4.查找

查找就是刷新适配器的意思,这个就不说了

四.RecyclerView条目点击效果,增删改查的实现

效果:
R2
这里只是简单的实现了增删改查操作,如果要实现具体的内容修改可以弹出对话框实现。
下面是程序设计的代码:

(一)activity_main.xml布局文件的设计

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical"    >    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="在第二条目位置增加数据"        android:onClick="add"        />    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="在第二条目位置删除数据"        android:onClick="delete"        />    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="在第二条目位置修改数据"        android:onClick="updata"        />    <android.support.v7.widget.RecyclerView        android:id="@+id/recyclerView"        android:layout_width="match_parent"        android:layout_height="match_parent"        /></LinearLayout>

(二)Item的布局文件和第一个示例是一样的

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal" android:layout_width="match_parent"    android:layout_height="50dp"><ImageView    android:layout_width="50dp"    android:layout_height="50dp"    android:id="@+id/imageView"    />    <TextView        android:layout_gravity="center"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/textView"        /></LinearLayout>

(三)适配器类的设计,这个适配器和上一个程序的适配器相似,但是这里把点击事件和长按事件回调接口封装出去了。

package com.example.recyclerviewdemo;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.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;/** * RecyclerViewAdaper适配器的创建 * 针对的数据类型Bean肯定是不同的,那么这里可能要引入泛型代表我们的Bean * 如果只是Int类型或String类型的数据,这里可以不用泛型 */public  class MyAdapter<T> extends RecyclerView.Adapter {    private ArrayList<T>  mDataset;//数据源    private Context mContexts;//上下文    private  int mLayoutID;//显示的条目的布局    //构造方法,传入上下文和数据源,条目的布局ID    public MyAdapter(Context contexts,int layoutID,ArrayList<T> myDataset) {        mContexts=contexts;        mDataset = myDataset;        mLayoutID=layoutID;    }    //第一个重要的方法,创建ViewHolder对象,也是这三个方法中最难理解的一个    //这个方法需要创建一个ViewHolder类(继承RecyclerView.ViewHolde)    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        //根据布局ID创建View对象        View v = LayoutInflater.from(parent.getContext()).inflate(mLayoutID, parent, false);        return new MyViewHolder(v);    }    //第二个重要的方法,绑定ViewHolder对象,这里可以避免多次的findViewById    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {        MyViewHolder  myHolder=(MyViewHolder)holder;//转换对象,成子类的对象,才能设置子类的属性        myHolder.image.setImageResource(R.mipmap.ic_launcher);//设置图片        myHolder.text.setText("---"+mDataset.get(position));//給文本设置内容        //給文本设置点击事件        myHolder.text.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //Toast.makeText(mContexts,"你点中了:"+mDataset.get(position),Toast.LENGTH_SHORT).show();                //判断如果监听对象不为空,也就是在其他地方进行了监听,就会触发这个方法                if (listenerClick!=null){                    //输入集合的数据                    listenerClick.OnClickListenerData(mDataset.get(position));                }            }        });        //給文本设置长按事件        myHolder.text.setOnLongClickListener(new View.OnLongClickListener() {            @Override            public boolean onLongClick(View v) {               // Toast.makeText(mContexts,"你长按了:"+mDataset.get(position),Toast.LENGTH_SHORT).show();                //判断如果监听对象不为空,也就是在其他地方进行了监听,就会触发这个方法                if (listenerClick!=null){                    //输入集合的数据                    listenerClick.OnLongClickListenerData(mDataset.get(position));                }                return true;//表示消化,不再重复触发点击            }        });        myHolder.itemView.setTag(myHolder);//设置Tag    }    //第三个重要的方法,返回显示的Item 的数量,这个也是最容易理解的!    @Override    public int getItemCount() {        return mDataset.size();    }    //创建一个自己的ViewHolder类继承自RecyclerView.ViewHolder    //要在里面实现一个次控件的创建,避免多次的创建或findViewById    public static class MyViewHolder extends RecyclerView.ViewHolder  {        private ImageView image;        private TextView text;        public MyViewHolder(View itemView) {            super(itemView);             image = (ImageView) itemView.findViewById(R.id.imageView);            text = (TextView) itemView.findViewById(R.id.textView);        }    }    //定义接口,可以在外部设置点击事件或长按事件     interface ListenerClick<T>{//在接口中定义了泛型才能在里面的方法中使用        abstract void  OnClickListenerData(T t);        abstract void  OnLongClickListenerData(T t);    }    //定义接口对象    private ListenerClick listenerClick;    //暴露传入接口对象的方法    public void setListenerClick(ListenerClick listenerClick) {        this.listenerClick = listenerClick;    }}

(四)主方法的类的设计,简单实现了增删改查操作

package com.example.recyclerviewdemo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.DefaultItemAnimator;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.OrientationHelper;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {   //定义RecyclerView组件    RecyclerView recyclerView;    //适配器    MyAdapter adapter;    //数据源    ArrayList<String> mDataset;    private RecyclerView.LayoutManager layoutManager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);        //创建布局管理器(这里是线性)        LinearLayoutManager layoutManager = new LinearLayoutManager(this );        //设置布局管理器        recyclerView.setLayoutManager(layoutManager);        //设置为垂直布局,这也是默认的        layoutManager.setOrientation(OrientationHelper. VERTICAL);        //设置默认的条目的显示的效果,当然也是可以自定义的        recyclerView.setItemAnimator(new DefaultItemAnimator());       //设置数据源         mDataset=new ArrayList<>();        for (int i = 0; i <20; i++) {            mDataset.add("行"+i);        }        //创建,设置Adapter,        //这里要传入上下文,Iten条目的布局ID,数据源三个元素,        // 这里还使用的泛型的写法(主要是针对数据源的扩展,因为很多程序中数据源都是Bean对象,那么这个泛型可以改成Bena类)         adapter=new MyAdapter<String>(this,R.layout.item,mDataset);        recyclerView.setAdapter(adapter);        //在这里设置点击事件或长按事件        adapter.setListenerClick(new MyAdapter.ListenerClick() {            @Override            public void OnClickListenerData(Object o) {                Toast.makeText(MainActivity.this,"你点中了:"+o.toString(),Toast.LENGTH_SHORT).show();            }            @Override            public void OnLongClickListenerData(Object o) {                Toast.makeText(MainActivity.this,"你长按了:"+o.toString(),Toast.LENGTH_SHORT).show();            }        });    }    int num=0;    //給RecyclerView添加数据,在position为2的位置添加数据    public void add(View view){         adapter.notifyItemInserted(2);        mDataset.add(2,"newDataString"+num++);        adapter.notifyItemRangeChanged(2, adapter.getItemCount());        //  adapter.notifyDataSetChanged();//可以看到没有任何动画效果    }    //給RecyclerView删除数据,在position为2的位置删除数据    public void delete(View view){         adapter.notifyItemRemoved(2);        mDataset.remove(2);         adapter.notifyItemRangeChanged(2, adapter.getItemCount());      //  adapter.notifyDataSetChanged();//可以看到没有任何动画效果    }    //給RecyclerView修改数据,在position为2的位置修改数据    public void updata(View view){       //  adapter.notifyItemRemoved(2);        mDataset.set(2,"newDataString"+num++);        adapter.notifyItemChanged(2);    }}

       上面就是RecyclerView的简单使用总结,后面我还会对一些复杂效果或功能做点总结。

4 0
原创粉丝点击