RecyclerView简介

RecyclerView是Android5.0提出的UI控件,通常用来代替传统的ListView。
其官方给出的定义如下:

A flexible view for providing a limited window into a large data set.

释义:灵活的视图提供一个有限的窗口变成一个大数据集。

从定义可以明白,Flexible(可扩展性) 是RecyclerView 显著的特点。

在使用RecyclerView的时候,需要在项目的build.gradle 中添加相应依赖库:

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

ListVIew 与 RecyclerView 的简单对比
  • 相同点:
  • 由于子布局是被ListView(RecyclerView)所包裹着,所以在获取子布局文件的View对象的时候必须调用
    View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,flase);
  • 需要自定义 Adapter (适配器)来对所需要的显示的数据进行处理。并借由此适配器,把数据按需求的显示到RecylerView 。
  • 优缺点对比:
  • ListView 相比 RecyclerView 优点:
  • 拥有addHeaderView(),addFooterView()添加头视图和尾视图。
  • 通过“android:divider”设置自定义分割线。
  • 拥有setOnItemClickListener() 和 setOnItemLongClickListener()设置点击事件和长按事件。

借由以上的这些方法,在RecyclerView 都没有直接可用的接口,所以再实现以上功能的时候,运用ListView比较合适。

  • RecyclerView 的优点
  • 默认实现View 的复用,不需要类似的If(convertView == null) 的判断实现前提。
  • 回收机制更加完善。
  • 默认支持局部刷新。
  • 容易实现添加Item,删除Item的动画效果
  • 容易实现拖拽、侧滑删除等功能。
  • 区别之一:
  • RecyclerView 将 ListView 中的 getView()功能拆分成了onCreateViewHolder() 和 onBinViewHolder()

RecyclerView 的 Adapter 实现相对于 ListView 繁琐,所以RecyclerView适合运用于,每个子布局是复杂的综合布局的情形。
而相对的若是显示的子布局为简单的TextVIew或ImagView布局,则使用ListView会更简单,高效。

RecyclerView 的四大组成

  • Adapter : 为 Item 提供数据
  • Layout Manager : Item 的布局
  • 布局形式:
  • LayoutManager :默认为纵向布局
  • LayoutManager.HORIZONTAL :横向布局
  • StaggeredGridLayoutManager :瀑布流布局

• Item Animator:添加、删除 Item 动画
• Item Decoration : Item 之间的 Divider(间隔线)
RecyclerView 的简单实现
  • 创建 Adapter(适配器) :
  • 主要功能是为了 RecyclerView 提供数据 ,简单的实现如下:
    创建一个继承RecyclerView.Adapter < DataAdapter.ViewHolder>的 Adapter 类,(其中的ViewHolder是DataAdapter的一个内部实现类)
    static class ViewHolder extends RecyclerView.ViewHolder
  • 创建ViewHolder 内部实现类:让该内部类继承RecyclerView.ViewHolder,具体实现细则与ListView中的ViewHolder一样。
  • 创建父布局缓存对象,子布局各个控件的空对象;借由重写ViewHolder方法,利用传入的父布局对象itemView,给各个控件的空对象加载实际的内容:
public ViewHolder(View itemView) {
        super(itemView);

        //用来保存子项最外层布局的实例
        DataView = itemView;
        //取Image和Text View的ID 进行实例化对象。
        DataImage = (ImageView) itemView.findViewById(R.id.image);
        DataName = (TextView) itemView.findViewById(R.id.name);
    }

(Data作为数据储存类,存放你想显示的数据)

  • 在 DataAdapter 中需要实现以下三个方法
  • DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType):用于映射Item Layout ID,并创建ViewHolder对象进行返回,还可以添加点击事件的处理。
  • void onBindViewHolder(WeatherAdapter.ViewHolder holder, int position):为holder设置指定数据(即为所选定的子布局中的Item设置希望显示的参数)
  • int getItemCount():返回加入Item的个数,等同一个计数器。
  • 基本的Adapter实现实例参考如下:
public class DataAdapter extends RecyclerView.Adapter< WeatherAdapter.ViewHolder > {

        private List<Data> mDataList;

        static class ViewHolder extends RecyclerView.ViewHolder {
        View DataView;
        ImageView DataImage;
        TextView DataName;

        public ViewHolder(View itemView) {
            super(itemView);

            //用来保存子项最外层布局的实例
            DataView = itemView;
            //取Image和Text View的ID 进行实例化对象。
            DataImage = (ImageView) itemView.findViewById(R.id.image);
            DataName = (TextView) itemView.findViewById(R.id.name);
        }
    }

    public DataAdapter(List<Data> DataList) {
        mDataList = DataList;
    }

    @Override
    public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        /**
         * 用inflate加载自定义的视图 weather_itme布局文件,也称为layout的映射
         *三个参数的含义:
         * 1.想要扩展的布局的资源ID
         * 2.将作为扩展布局父项的ViewGroup
         * 3.指示是否应该在扩展期间将扩展布局附加至root的布尔值
         */

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itme, parent, false);

        //创建布局缓存对象,最后返回
        final ViewHolder holder = new ViewHolder(view);

        return holder;
    }

    /**
     * 对RecyclerView子项的数据进行复制,会在每个子项被滚动到屏幕内的时候执行
     *      再将数据设置到ViewHolder的IMageView和TextView当中
     * @param holder  ViewHolder的实例
     * @param position 用于得到当前项的Weather实例
     */
    @Override
    public void onBindViewHolder(DataAdapter.ViewHolder holder, int position) {

        Data data = mDataList.get(position);
        holder.DataImage.setImageResource(data.getImageId());
        holder.DataName.setText(data.getName());

    }

    /**
     *
     * @return 返回RecyclerView一共有多少子项,直接返回数据源的长度
     */
    @Override
    public int getItemCount() {
        return mDataList.size();
        }
    }
RecyclerView 点击事件的实现
  • 实现思路:
  • (通常把点击事件设置在Adapter的onCreateViewHolder 方法中,使得在刚加载数据的时候就实现了子Item的点击事件)
  • 获取包裹子Item的父布局View对象。
  • 利用 View 对象对子Item中所需要设置点击事件的控件实例添加设置点击监听。
  • 在监听事件中,实现OnClick(View view)对点击事件的具体操作。
  • 简单的实现形式可参照下:
//给父布局整个布局设计点击事件
        holder.weatherView.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition(); 
                //判断其点击的是哪一个模块 返回它的的下标
                weather Weather = mWeatherList.get(position);
                //通过返回的下标,取到其名称
                Toast.makeText(view.getContext(), "you clicker view  " + Weather.getName(), Toast.LENGTH_SHORT).show();
            }
        });

        //给父布局中的子控件ImageView 设置点击事件
        holder.weatherImage.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition();
                weather Weather = mWeatherList.get(position);
                Toast.makeText(view.getContext(), "you clicker image  " + Weather.getName(), Toast.LENGTH_SHORT).show();
            }
        });

参考资料