RecyclerView的那点事儿

来源:互联网 发布:菲律宾淘宝 编辑:程序博客网 时间:2024/05/16 17:15

RecyclerView

控件简介

  • ListView的升级版
  • LinearLayoutManager
  • GridLayoutManager
  • StaggeredGridLayoutManager
  • 定制Item动画,指定Item之间的分隔线

RecyclerView相关的重要类

  • Adapter
  • ViewHolder
  • LayoutManager
  • ItemDecoration
  • ItemAnimator

添加RecyclerView控件依赖包

Android Studio开发工具,在本项目的build.gradle文件中添加

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

如果是eclipse的话,下载jar包,放到lib下,一般都会自动的build path,检查下即可。

如何下载jar ?
在SDK Manager中下载Support Library
这里写图片描述

sdk\extras\android\support\v7\recyclerview\libs

这里写图片描述

为Recycler准备数据

package demo.turing.com.materialdesignwidget.recyclerView;import java.util.ArrayList;import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;/** * MyApp * * @author Mr.Yang on 2016-03-30  20:21. * @version 1.0 * @desc */public class SimulatorData {    public static ArrayList<SampleModel> getSampleModelData(int size) {        ArrayList<SampleModel> sampleData = new ArrayList<SampleModel>(size);        for (int i = 0; i < size; i++) {            sampleData.add(new SampleModel("新的列表项< " + i + " >"));        }        return sampleData;    }}
package demo.turing.com.materialdesignwidget.recyclerView.model;/** * MyApp * * @author Mr.Yang on 2016-03-30  20:23. * @version 1.0 * 对应Item中药显示的数据项 */public class SampleModel {    private String text;    public SampleModel(String text) {        this.text = text;    }    public String getText() {        return text;    }    public void setText(String text) {        this.text = text;    }}

绘制列表项之间的分隔线

这里写图片描述

package demo.turing.com.materialdesignwidget.recyclerView;import android.content.Context;import android.content.res.TypedArray;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;/** * MyApp * * @author Mr.Yang on 2016-03-30  20:37. * @version 1.0 *          分隔条 * * *   DividerItemDecoration  https://gist.github.com/alexfu/0f464fc3742f134ccd1e */public class DividerItemDecoration extends RecyclerView.ItemDecoration {    // 默认分隔条Drawable资源的ID,使用系统自带的    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;    private Drawable mDivider;    private int mOrientation;    public DividerItemDecoration(Context context, int orientation) {        // 使用TypedArray装载定义的ATTRS        final TypedArray a = context.obtainStyledAttributes(ATTRS);        // 获取系统提供的分隔条Drawable对象        mDivider = a.getDrawable(0);        // 回收TypedArray所占用的空间        a.recycle();        setOrientation(orientation);    }    /**     * 设置item的显示 水平 or 垂直     *     * @param orientation     */    public void setOrientation(int orientation) {        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {            throw new IllegalArgumentException("invalid orientation");        }        mOrientation = orientation;    }    @Override    public void onDraw(Canvas c, RecyclerView parent) {        if (mOrientation == VERTICAL_LIST) {            drawVertical(c, parent);        } else {            drawHorizontal(c, parent);        }    }    public void drawVertical(Canvas c, RecyclerView parent) {        final int left = parent.getPaddingLeft();        final int right = parent.getWidth() - parent.getPaddingRight();        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            RecyclerView v = new android.support.v7.widget.RecyclerView(                    parent.getContext());            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    public void drawHorizontal(Canvas c, RecyclerView parent) {        final int top = parent.getPaddingTop();        final int bottom = parent.getHeight() - parent.getPaddingBottom();        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    @Override    public void getItemOffsets(Rect outRect, int itemPosition,                               RecyclerView parent) {        if (mOrientation == VERTICAL_LIST) {            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());        } else {            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);        }    }}

实现Adapter

package demo.turing.com.materialdesignwidget.recyclerView.adapter;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;import java.util.Random;import demo.turing.com.materialdesignwidget.R;import demo.turing.com.materialdesignwidget.recyclerView.SimulatorData;import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;/** * MyApp * * @author Mr.Yang on 2016-03-30  21:03. * @version 1.0 * @desc */public class SampleRecyclerAdapter extends RecyclerView.Adapter<SampleRecyclerAdapter.ViewHolder> {    // 模拟数据    private  ArrayList<SampleModel> sampleData = SimulatorData.getSampleModelData(20);    /**     * 用于创建控件     *     * @param parent     * @param viewType     * @return     */    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        // 获得列表项控件(LinearLayer对象)        // list_basic_item.xml布局文件中只包含一个<LinearLayer>标签,        // 在该标签中包含了一个<TextView>标签, item是LinearLayout对象        View item = LayoutInflater.from(parent.getContext()).inflate(                R.layout.list_basic_item, parent, false);        ViewHolder viewHolder = new ViewHolder(item);        return viewHolder;    }    /**     * 为控件设置数据     *     * @param holder     * @param position     */    @Override    public void onBindViewHolder(ViewHolder holder, int position) {        //  获取当前item中显示的数据        final SampleModel rowData = sampleData.get(position);        //  设置要显示的数据        holder.textViewSample.setText(rowData.getText());        // 设置tag        holder.itemView.setTag(rowData);    }    @Override    public int getItemCount() {        return sampleData.size();    }    /**     * 删除指定的Item     *     * @param position     */    public void removeData(int position) {        sampleData.remove(position);        //  通知RecyclerView控件某个Item已经被删除        notifyItemRemoved(position);    }    /**     * 在指定位置添加一个新的Item     *     * @param positionToAdd     */    public void addItem(int positionToAdd) {        sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));        //  通知RecyclerView控件插入了某个Item        notifyItemInserted(positionToAdd);    }    /**     * 对应Item中的控件     */    public static class ViewHolder extends RecyclerView.ViewHolder {        private final TextView textViewSample;        public ViewHolder(View itemView) {            super(itemView);            textViewSample = (TextView) itemView                    .findViewById(R.id.textViewSample);        }    }}

完成使用RecyclerView控件的最后工作

package demo.turing.com.materialdesignwidget.recyclerView;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import demo.turing.com.materialdesignwidget.R;import demo.turing.com.materialdesignwidget.recyclerView.adapter.SampleRecyclerAdapter;public class RecyclerViewAct extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_recycler_view);        // 获取RecyclerView对象        RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);        //  创建线性布局管理器(默认是垂直方向)        LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);        //  为RecyclerView指定布局管理对象        recyclerView.setLayoutManager(layoutManager);        //  创建列表项分隔线对象        RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST);        //  为RecyclerView控件指定分隔线对象        recyclerView.addItemDecoration(itemDecoration);        SampleRecyclerAdapter sampleRecyclerAdapter = new SampleRecyclerAdapter();        recyclerView.setAdapter(sampleRecyclerAdapter);    }}

效果图

这里写图片描述

定制个性化分隔条

drawable\divider_custom.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <size android:height="4dp"></size>    <!--渐变色-->    <gradient        android:centerColor="#ff0000ff"        android:endColor="#ffff0000"        android:startColor="#ffff0000"        android:type="linear"></gradient></shape>

主题中设置

  <item name="android:listDivider">@drawable/divider_custom</item>

瀑布流

StaggeredGridLayuoutAct.java

package demo.turing.com.materialdesignwidget.recyclerView;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import java.util.List;import demo.turing.com.materialdesignwidget.R;import demo.turing.com.materialdesignwidget.recyclerView.adapter.StaggeredGridLayoutAdapter;import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;/** * 不采用分隔线, 在Item的布局中 采用layout_margin的方式 * * 主要是动态设置View的高度 adapter类中的 onBindViewHolder */public class StaggeredGridLayuoutAct extends AppCompatActivity {    private RecyclerView recyclerView ;    // 模拟数据    private List<SampleModel> sampleData = SimulatorData.getSampleModelData(20);    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_staggered_grid_layuout);        // 查找组件        recyclerView = (RecyclerView) findViewById(R.id.id_rv_staggered);        // 创建布局管理器  -3列,垂直        StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);        // 设置布局        recyclerView.setLayoutManager(manager);        // Adapter        StaggeredGridLayoutAdapter adapter = new StaggeredGridLayoutAdapter(this,sampleData);        recyclerView.setAdapter(adapter);    }}

activity_staggered_grid_layuout.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"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="demo.turing.com.materialdesignwidget.recyclerView.StaggeredGridLayuoutAct">    <android.support.v7.widget.RecyclerView        android:id="@+id/id_rv_staggered"        android:layout_width="match_parent"        android:layout_height="match_parent"></android.support.v7.widget.RecyclerView></RelativeLayout>

StaggeredGridLayoutAdapter.java

package demo.turing.com.materialdesignwidget.recyclerView.adapter;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;import java.util.List;import demo.turing.com.materialdesignwidget.R;import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;/** * MyApp * * @author Mr.Yang on 2016-03-31  20:19. * @version 1.0 * @desc */public class StaggeredGridLayoutAdapter extends RecyclerView.Adapter<StaggeredGridLayoutAdapter.ViewHolder> {    private Context context;    private List<SampleModel> datas;    private LayoutInflater inflater;    // 随机高度的结合    private List<Integer> mHeights;    /**     * 构造函数     *     * @param context     * @param datas     */    public StaggeredGridLayoutAdapter(Context context, List<SampleModel> datas) {        this.context = context;        this.datas = datas;        this.inflater = LayoutInflater.from(context);        // 初始化随机高度的集合        mHeights = new ArrayList<>();        for (int i = 0; i < datas.size(); i++) {            mHeights.add((int)(100 + Math.random() * 300));        }    }    @Override    public StaggeredGridLayoutAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        // 动态加载Item的布局文件        View view = inflater.inflate(R.layout.list_basic_item, parent, false);        // 实例化ViewHolder        ViewHolder viewHolder = new ViewHolder(view);        return viewHolder;    }    @Override    public void onBindViewHolder(StaggeredGridLayoutAdapter.ViewHolder holder, int position) {        // 获取当前Item中的显示的数据        SampleModel sampleModel = datas.get(position);        //设置控件的随机高度        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();        lp.height = mHeights.get(position);        holder.itemView.setLayoutParams(lp);        // 设置组件的值        holder.textView.setText(sampleModel.getText());        // 设置tag        holder.itemView.setTag(sampleModel);    }    @Override    public int getItemCount() {        return datas.size();    }    /**     * ViewHoder     */    class ViewHolder extends RecyclerView.ViewHolder {        TextView textView;        public ViewHolder(View itemView) {            super(itemView);            textView = (TextView) itemView                    .findViewById(R.id.textViewSample);        }    }}

list_basic_item.xml

<?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"    android:layout_margin="3dp"    android:background="#6495ED"    android:gravity="center"    android:orientation="horizontal">    <TextView        android:id="@+id/textViewSample"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="20sp"        android:text="演示"/></RelativeLayout>

效果图

这里写图片描述

动画效果

 // 默认动画效果 recyclerView.setItemAnimator(new DefaultItemAnimator());

notifyItemRemoved(position)

 /**     * 删除指定的Item     *     * @param position     */    public void removeData(int position) {        sampleData.remove(position);        //  通知RecyclerView控件某个Item已经被删除        notifyItemRemoved(position);    }

notifyItemInserted(positionToAdd)

    /**     * 在指定位置添加一个新的Item     *     * @param positionToAdd     */    public void addItem(int positionToAdd) {        sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));        //  通知RecyclerView控件插入了某个Item        notifyItemInserted(positionToAdd);    }

为RecyclerView添加item的点击事件

方法一:利用回调的方式实现(不太完善,仍可实现)

实现步骤如下:
在adapter类中,定义接口,接口中定义两个方法分别对应click和longClick,定义完接口,添加接口和设置Adapter接口的方法:

  /**     * 接口 ,提供两个方法     */    public interface OnRecyclerViewItemClickListener{        // 单击事件        void onItemClick(View view ,int position);        // 长按触发的事件        void onItemLongClick(View view ,int position);    }    // 定义OnRecyclerViewItemClickListener对象    public OnRecyclerViewItemClickListener  mOnRecyclerViewItemClickListener ;    // 暴漏给外部的set方法,持有OnRecyclerViewItemClickListener对象    public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener){        this.mOnRecyclerViewItemClickListener = listener ;    }

在onBindViewHolder方法中

 // 点击事件        if(mOnRecyclerViewItemClickListener != null){            // click            holder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    mOnRecyclerViewItemClickListener.onItemClick(holder.itemView,position);                }            });            // longClick            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    mOnRecyclerViewItemClickListener.onItemLongClick(holder.itemView,position);                    return false;                }            });        }

做完这些事情,我们就可以在Activity或其他地方为RecyclerView添加项目点击事件了,

// 设置监事件        sampleRecyclerAdapter.setOnRecyclerViewItemClickListener(new SampleRecyclerAdapter.OnRecyclerViewItemClickListener() {            @Override            public void onItemClick(View view, int position) {                Toast.makeText(RecyclerViewAct.this,"Click" + position ,Toast.LENGTH_SHORT).show();            }            @Override            public void onItemLongClick(View view, int position) {                Toast.makeText(RecyclerViewAct.this,"LongClick" + position ,Toast.LENGTH_SHORT).show();            }        });

完整代码如下:

RecyclerViewAct

package demo.turing.com.materialdesignwidget.recyclerView;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.DefaultItemAnimator;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;import android.widget.Toast;import demo.turing.com.materialdesignwidget.R;import demo.turing.com.materialdesignwidget.recyclerView.adapter.SampleRecyclerAdapter;public class RecyclerViewAct extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_recycler_view);        // 获取RecyclerView对象        RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);        //  创建线性布局管理器(默认是垂直方向)        LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);        //  为RecyclerView指定布局管理对象        recyclerView.setLayoutManager(layoutManager);        //  创建列表项分隔线对象        RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST);        //  为RecyclerView控件指定分隔线对象        recyclerView.addItemDecoration(itemDecoration);        // 默认动画效果        recyclerView.setItemAnimator(new DefaultItemAnimator());        SampleRecyclerAdapter sampleRecyclerAdapter = new SampleRecyclerAdapter();        recyclerView.setAdapter(sampleRecyclerAdapter);        // 设置监事件        sampleRecyclerAdapter.setOnRecyclerViewItemClickListener(new SampleRecyclerAdapter.OnRecyclerViewItemClickListener() {            @Override            public void onItemClick(View view, int position) {                Toast.makeText(RecyclerViewAct.this,"Click" + position ,Toast.LENGTH_SHORT).show();            }            @Override            public void onItemLongClick(View view, int position) {                Toast.makeText(RecyclerViewAct.this,"LongClick" + position ,Toast.LENGTH_SHORT).show();            }        });    }}

SampleRecyclerAdapter

package demo.turing.com.materialdesignwidget.recyclerView.adapter;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;import java.util.Random;import demo.turing.com.materialdesignwidget.R;import demo.turing.com.materialdesignwidget.recyclerView.SimulatorData;import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;/** * MyApp * * @author Mr.Yang on 2016-03-30  21:03. * @version 1.0 * @desc * * * RecyclerView  点击事件 请看http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1118/2004.html*/public class SampleRecyclerAdapter extends RecyclerView.Adapter<SampleRecyclerAdapter.ViewHolder> {    // 模拟数据    private  ArrayList<SampleModel> sampleData = SimulatorData.getSampleModelData(20);    /**     * 接口 ,提供两个方法     */    public interface OnRecyclerViewItemClickListener{        // 单击事件        void onItemClick(View view ,int position);        // 长按触发的事件        void onItemLongClick(View view ,int position);    }    // 定义OnRecyclerViewItemClickListener对象    public OnRecyclerViewItemClickListener  mOnRecyclerViewItemClickListener ;    // 暴漏给外部的set方法,持有OnRecyclerViewItemClickListener对象    public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener){        this.mOnRecyclerViewItemClickListener = listener ;    }    /**     * 用于创建控件     *     * @param parent     * @param viewType     * @return     */    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        // 获得列表项控件(LinearLayer对象)        // list_basic_item.xml布局文件中只包含一个<LinearLayer>标签,        // 在该标签中包含了一个<TextView>标签, item是LinearLayout对象        View item = LayoutInflater.from(parent.getContext()).inflate(                R.layout.list_basic_item, parent, false);        ViewHolder viewHolder = new ViewHolder(item);        return viewHolder;    }    /**     * 为控件设置数据     *     * @param holder     * @param position     */    @Override    public void onBindViewHolder(final ViewHolder holder, final int position) {        //  获取当前item中显示的数据        final SampleModel rowData = sampleData.get(position);        //  设置要显示的数据        holder.textViewSample.setText(rowData.getText());        // 设置tag        holder.itemView.setTag(rowData);         // 点击事件 if(mOnRecyclerViewItemClickListener != null){            // click        holder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    // 通过getLayoutPosition,防止position错位                    int layoutPosition = holder.getLayoutPosition();                    mOnRecyclerViewItemClickListener.onItemClick(holder.itemView,layoutPosition);                }            });            // longClick            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    int layoutPosition = holder.getLayoutPosition();                    mOnRecyclerViewItemClickListener.onItemLongClick(holder.itemView,layoutPosition);                    return false;                }            });        }    }    @Override    public int getItemCount() {        return sampleData.size();    }    /**     * 删除指定的Item     *     * @param position     */    public void removeData(int position) {        sampleData.remove(position);        //  通知RecyclerView控件某个Item已经被删除        notifyItemRemoved(position);    }    /**     * 在指定位置添加一个新的Item     *     * @param positionToAdd     */    public void addItem(int positionToAdd) {        sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));        //  通知RecyclerView控件插入了某个Item        notifyItemInserted(positionToAdd);    }    /**     * 对应Item中的控件     */    public static class ViewHolder extends RecyclerView.ViewHolder {        private final TextView textViewSample;        public ViewHolder(View itemView) {            super(itemView);            textViewSample = (TextView) itemView                    .findViewById(R.id.textViewSample);        }    }}

方法二:使用观察者模式实现

原理:
为RecyclerView的每个子item设置setOnClickListener,然后在onClick中再调用一次对外封装的接口,将这个事件传递给外面的调用者。而“为RecyclerView的每个子item设置setOnClickListener”在Adapter中设置。其实直接在onClick中也能完全处理item的点击事件,但是这样会破坏代码的逻辑。

步骤
在自定义的adapter(记得implements View.OnClickListener,下面有个onClick方法)中定义如下接口,模拟ListView的OnItemClickListener:

 //define interface public static interface OnRecyclerViewItemClickListener {        void onItemClick(View view , String data);    }

声明一个这个接口的变量:

  private OnRecyclerViewItemClickListener mOnItemClickListener = null;

在onCreateViewHolder()中为每个item添加点击事件:

 @Override    public ViewHolder onCreateViewHolder(ViewGroup viewGroup,  int viewType) {        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);        ViewHolder vh = new ViewHolder(view);        //将创建的View注册点击事件        view.setOnClickListener(this);        return vh;    }

将点击事件转移给外面的调用者:

 @Override    public void onClick(View v) {        if (mOnItemClickListener != null) {            //注意这里使用getTag方法获取数据            mOnItemClickListener.onItemClick(v,(String)v.getTag());        }    }

意上面调用接口的onItemClick()中的v.getTag()方法,这需要在onBindViewHolder()方法中设置和item相关的数据

@Override    public void onBindViewHolder(ViewHolder viewHolder,  int position) {        viewHolder.mTextView.setText(datas[position]);        //将数据保存在itemView的Tag中,以便点击时进行获取        viewHolder.itemView.setTag(datas[position]);    }

最后暴露给外面的调用者,定义一个设置Listener的方法():

 public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {        this.mOnItemClickListener = listener;    }

以上所有步骤都发生在自定义的adapter中,典型的观察者模式,有点绕的地方在于,这里涉及到两个观察者模式的使用,view的setOnClickListener本来就是观察者模式,我们将这个观察者模式的事件监听传递给了我们自己的观察者模式。

在Activity中使用

mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);        //创建默认的线性LayoutManager        mLayoutManager = new LinearLayoutManager(this);        mRecyclerView.setLayoutManager(mLayoutManager);        //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能        mRecyclerView.setHasFixedSize(true);        //创建并设置Adapter        mAdapter = new MyAdapter(data);        mRecyclerView.setAdapter(mAdapter);        mAdapter.setOnItemClickListener(new OnRecyclerViewItemClickListener(){            @Override                public void onItemClick(View view , String data){                Toast.makeText(MainActivity.this, data, 600).show();            }        });

~

RecyclerView添加Header

。。。。。。

5 0
原创粉丝点击