Android 开发之RecyclerView的使用

来源:互联网 发布:swift model数组 编辑:程序博客网 时间:2024/06/04 19:51

Android 开发之RecyclerView的使用

本篇博客主要参考 鸿洋大神的文章进行编写,如有意见,请告知,原博客地址:(http://blog.csdn.net/lmj623565791/article/details/45059587)

充分利用时间,总结最近一直在研究的一个很实用的控件,以做如下分享:

自android 5.0后,谷歌推出了RecyclerView控件,那么我接下来从它的定义、优点、使用方法及简单拓展进行总结,意在使更多的开发替换ListView,如有错误与误导性语言和表达,请留言指出。

  • RecyclerView 的定义
  • RecyclerView 与 ListView 相比较的优点
  • RecyclerView 的简单使用
  • RecyclerView 的Adapter使用
  • RecyclerView 增加分隔线以及修改分隔线样式
  • RecyclerView 的条目点击事件
  • RecyclerView 结合MaterialRefreshLayout 构成流畅而优雅的刷新和加载更多

1.RecyclerView 定义

该控件是support-7包里的新控件,是一个强大的滑动控件,根据官方的介绍翻译:该控件用于在有限的显示窗口展示大量的数据集,所以其本质原理和ListView是相类似的,从它的名字也不难判断出,其实现原理肯定涉及复用问题,那已经有了ListView为什么还要更推崇RecyclerView呢?这就推及到第二个问题了。

2.RecyclerView 与 ListView 的比较

通过使用RecyclerView控件,我们可以在APP中创建带有Material Design风格的复杂列表。既然官方推荐使用,那肯定存在着较ListView过人之处,现在就RecyclerView的优点进行罗列:

  • (1) RecylerView 对于原有的ViewHolder回收复用功能进行了封装,也就是说RecylerView标准化了ViewHolder,编写Adapter时面向的是ViewHolder而不再是View,复用的逻辑被封装了,写起来更加简单
  • (2) 其拥有强大的可扩展性,高度的解耦,异常的灵活的特性。例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还有StaggeredGridLayoutManager等),也就是说RecylerView不再拘泥于ListView的线性展示方式,它也可以实现GridView、瀑布流等多种效果。
  • (3) 有可控的Item分隔线,通过继承RecylerView的ItemDecoration这个类定义添加,然后针对自己的业务需求去抒写代码。
  • (4) 可以控制Item增删的动画,通过ItemAnimator这个类进行控制,当然针对增删的动画,RecylerView有其自己默认的实现。

3.RecyclerView 的简单使用(以AS为例)

接下来就让我们看看,这个神奇的控件的使用:

3.1 初步使用

  • 添加依赖
dependencies {...compile 'com.android.support:recyclerview-v7:21.0.+'}
  • 使用步骤
首先我们先看下布局的实现:<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=".MainActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/my_recycler_view"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:scrollbars="vertical"/></RelativeLayout>
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());  

可以从上面的使用步骤看出,相较于ListView的使用更加复杂了,这也就是RecyclerView具有高度的解偶性的表现,所谓舍得,即便代码书写增加了复杂性,但换回了可扩展性的增加。
接下来我们来继续了解RecyclerView的Adapter的使用,其实这和ListView的Adapter还是有区别的,RecyclerView的Adapter只实现三个固定方法:

  • (1) onCreateViewHolder()
    这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例。当然,这个ViewHolder需要我们自己去编写。这样的好处就是直接省去了原先编写Listview的Adapter时的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
  • (2) onBindViewHolder()
    这个方法主要用于绑定数据到View中。方法给我们提供了一个viewHolder(自定义继承了RecyclerView 的 ViewHolder 的类型),而不是原来的convertView。
  • (3) getItemCount()
    这个方法就类似于BaseAdapter的getCount方法了,可获取总共有多少个条目。

接下来我们写个小的案例,直观展示:

每个条目的布局展示<?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="wrap_content"    android:orientation="vertical">    <TextView        android:id="@+id/tv_name"        android:layout_width="match_parent"        android:layout_height="@dimen/space_50dp"        android:gravity="center"        android:text="测试"        /></LinearLayout>
整体代码(其中使用了注解库ButterKnife)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 com.adjuz.myyupaopao.R;import com.adjuz.myyupaopao.base.BaseActivity;import com.cjj.MaterialRefreshLayout;import java.util.ArrayList;import butterknife.BindView;import butterknife.ButterKnife;/** * Created by shanfuming on 2017/4/20. */public class RecyclerviewAc extends BaseActivity {    private ArrayList<String> mData = new ArrayList<>();    @BindView(R.id.recycleView)    RecyclerView mRecyclerView;    @BindView(R.id.mrl_refreshLayout)    MaterialRefreshLayout materialRefreshLayout;    private MyAdapter myAdapter;    @Override    protected void initView() {        setContentView(R.layout.activity_recyclerviewac);        ButterKnife.bind(this);    }    @Override    protected void initData() {        for (int i = 0; i < 40; i++) {            mData.add("展示-" + i);        }        myAdapter = new MyAdapter(mData);        //设置布局管理器        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);        //这个是默认设置的(横纵向滑动展示)        linearLayoutManager.setOrientation(OrientationHelper.VERTICAL);        //linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);        //设置为Grid布局,需添加此布局管理器        //linearLayoutManager = new GridLayoutManager(context,columNum);mRecyclerView.setLayoutManager(linearLayoutManager);        //设置Adapter        mRecyclerView.setAdapter(myAdapter);    }    class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{        private ArrayList<String> mList;        private LayoutInflater inflater;        public MyAdapter(ArrayList<String> list) {            this.mList = list;            inflater = LayoutInflater.from(RecyclerviewAc.this);        }        /**         * 返回我们自定义继承了ViewHolder 的MyViewHolder         * @param parent         * @param viewType         * @return         */        @Override        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {            View view = inflater.inflate(R.layout.item_recyclerview,parent,false);            MyViewHolder myViewHolder = new MyViewHolder(view);            return myViewHolder;        }        /**         * 将view 与数据进行绑定         * @param holder         * @param position         */        @Override        public void onBindViewHolder(MyViewHolder holder, int position) {            holder.textView.setText(mList.get(position));        }        /**         * 返回数据的总个数         * @return         */        @Override        public int getItemCount() {            return mList.size();        }        class MyViewHolder extends RecyclerView.ViewHolder{            @BindView(R.id.tv_name)            TextView textView;            public MyViewHolder(View itemView) {                super(itemView);                ButterKnife.bind(this,itemView);            }        }    }}

效果如下:看起来和ListView实现的效果没区别。
效果图

完成这个小案例,大家有没有觉得这个控件的好处呢,Adapter的书写,onCreateViewHolder()中初始化View,然后返回一个ViewHolder,其实就相当于ListView的Adapter中的getView()中的contentView.getTag(),包括之后的数据绑定,整体都变得更加的简洁且清晰。现在确实很不符合审美,最起码应该加上分割线,接下来就到这个模块了。

3.2 RecyclerView 添加分割线

当我们去寻找类似Listview的divider属性时,会发现RecyclerView根本不支持这个属性,那我们怎么办呢?之前我们说过,可以通过RecyclerView.addItemDecoration(ItemDecoration decoration)这个方法进行设置,其中它需要的参数就是自己定义的继承自ItemDecoration的一个对象。当然像我们上面的例子ItemDecoration我们并没有设置也可以正常运行,那说明ItemDecoration并不是强制需要使用,作为开发者可以设置或者不设置Decoration。系统为我们提供了ItemDecoration,该类为抽象类,官方目前并没有提供默认的实现类,具体源码如下:

public static abstract class ItemDecoration {           public void onDraw(Canvas c,RecyclerView parent,State state) {             onDraw(c,parent);         }         public void onDrawOver(Canvas c,RecyclerView parent,State state) {             onDrawOver(c,parent);         }         public void getItemOffsets(RectoutRect, View view,RecyclerView parent,State state) {             getItemOffsets(outRect,((LayoutParams)view.getLayoutParams()).getViewLayoutPosition(),parent);         }     } 

当我们调用mRecyclerView.addItemDecoration()方法添加decoration的时候,RecyclerView在绘制的时候,调用该类的onDraw和onDrawOver方法

  • onDraw方法先于drawChildren

  • onDrawOver在drawChildren之后,一般我们选择复写其中一个即可。

  • getItemOffsets 可以通过outRect.set()为每个Item设置一定的偏移量,主要用于绘制Decorator。

接下来我们看一下RecyclerView.ItemDecoration的实现类,该类很好的实现了RecyclerView添加分割线(当使用LayoutManager为LinearLayoutManager时)。

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.support.v7.widget.RecyclerView.State;import android.util.Log;import android.view.View;/** * 这个类是v-7包中自带的,并不是我自定义的 */public class DividerItemDecoration extends RecyclerView.ItemDecoration {    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) {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();        setOrientation(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) {        Log.v("recyclerview - itemdecoration", "onDraw()");        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);            android.support.v7.widget.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);        }    }}

该类可设置横纵向分割线,我们在源代码的基础上加一句代码即可(此默认颜色为灰色,先不展示效果了):

mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));

该分割线是系统默认提供的,你可以在theme.xml中找到该属性的使用情况。这样方便我们去随意的改变,该属性我们可以直接声明在:

<!-- Application theme. -->    <style name="AppTheme" parent="AppBaseTheme">      <item name="android:listDivider">@drawable/divider_bg</item>      </style>

然后自己写个drawable即可,下面我们自编辑分隔符样式:

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

带有自定义分隔符的效果图

当然这个样式是可以随意玩的。

不过写到这里,确实看起来和Listview 展示没区别,而且代码更烦了,但是不要着急,接下来我们尝试GridView的实现,你会发现,修改起来十分方便:

上边我们使用的代码是这样的://设置布局管理器        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);        //这个是默认设置的        linearLayoutManager.setOrientation(OrientationHelper.VERTICAL);        mRecyclerView.setLayoutManager(linearLayoutManager);

我们之前简单介绍过它的布局管理器:当实现GridView时,我们直接替换使用GridLayoutManager(表格布局)即可,修改分分钟解决:

mRecyclerView.setLayoutManager(new GridLayoutManager(this,4));//StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);

这样对于前面的分割线就不再适用了,因为DividerItemDecoration 的计算绘制,是针对一行多个item进行的,但是GridView 是多行了,所以就要进行多次绘制,并且GridLayoutManager时,Item如果为最后一列(则右边无间隔线)或者为最后一行(底部无分割线)。

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);              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);          }

接下来我们直接引用 鸿洋大神 定义的分割线了:

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.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.RecyclerView.LayoutManager;import android.support.v7.widget.RecyclerView.State;import android.support.v7.widget.StaggeredGridLayoutManager;import android.view.View;/** *  * @author zhy *  */public class DividerGridItemDecoration extends RecyclerView.ItemDecoration{    private static final int[] ATTRS = new int[] { android.R.attr.listDivider };    private Drawable mDivider;    public DividerGridItemDecoration(Context context)    {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();    }    @Override    public void onDraw(Canvas c, RecyclerView parent, State state)    {        drawHorizontal(c, parent);        drawVertical(c, parent);    }    private int getSpanCount(RecyclerView parent)    {        // 列数        int spanCount = -1;        LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager)        {            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();        } else if (layoutManager instanceof StaggeredGridLayoutManager)        {            spanCount = ((StaggeredGridLayoutManager) layoutManager)                    .getSpanCount();        }        return spanCount;    }    public void drawHorizontal(Canvas c, RecyclerView parent)    {        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.getLeft() - params.leftMargin;            final int right = child.getRight() + params.rightMargin                    + mDivider.getIntrinsicWidth();            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    public void drawVertical(Canvas c, RecyclerView parent)    {        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 top = child.getTop() - params.topMargin;            final int bottom = child.getBottom() + params.bottomMargin;            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicWidth();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    private boolean isLastColum(RecyclerView parent, int pos, int spanCount,            int childCount)    {        LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager)        {            if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边            {                return true;            }        } else if (layoutManager instanceof StaggeredGridLayoutManager)        {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            if (orientation == StaggeredGridLayoutManager.VERTICAL)            {                if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边                {                    return true;                }            } else            {                childCount = childCount - childCount % spanCount;                if (pos >= childCount)// 如果是最后一列,则不需要绘制右边                    return true;            }        }        return false;    }    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,            int childCount)    {        LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager)        {            childCount = childCount - childCount % spanCount;            if (pos >= childCount)// 如果是最后一行,则不需要绘制底部                return true;        } else if (layoutManager instanceof StaggeredGridLayoutManager)        {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            // StaggeredGridLayoutManager 且纵向滚动            if (orientation == StaggeredGridLayoutManager.VERTICAL)            {                childCount = childCount - childCount % spanCount;                // 如果是最后一行,则不需要绘制底部                if (pos >= childCount)                    return true;            } else            // StaggeredGridLayoutManager 且横向滚动            {                // 如果是最后一行,则不需要绘制底部                if ((pos + 1) % spanCount == 0)                {                    return true;                }            }        }        return false;    }    @Override    public void getItemOffsets(Rect outRect, int itemPosition,            RecyclerView parent)    {        int spanCount = getSpanCount(parent);        int childCount = parent.getAdapter().getItemCount();        if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部        {            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);        } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边        {            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());        } else        {            outRect.set(0, 0, mDivider.getIntrinsicWidth(),                    mDivider.getIntrinsicHeight());        }    }}

不要忘记修改代码:

DividerGridItemDecoration dividerGridItemDecoration = new DividerGridItemDecoration(this);        mRecyclerView.addItemDecoration(dividerGridItemDecoration);

这里写图片描述

怎么样,到这里,是不是觉得RecyclerView真的很强大了,样式的切换只需要几行代码的改变,如此简便!还有横向的滑动效果(这里就不展示效果了,可以写下试试):

StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.HORIZONTAL);  //设置布局管理器  mRecyclerView.setLayoutManager(layoutManager);  

值得注意的是,当StaggeredGridLayoutManager布局管理器的第二个参数是StaggeredGridLayoutManager.VERTICAL时,第一个传入的int参数代表是行数;当StaggeredGridLayoutManager布局管理器的第二个参数是StaggeredGridLayoutManager.HORIZONTAL时,第一个传入的int参数代表是列数,这个效果和上边的是一样的;

可以看到,固定行数或列数,随意改变横向纵向,要注意的是,横向滑动时,要改变下item 布局的宽度,具体什么原因,大家写写就知道了。

4.RecyclerView 条目的增加与删除(包括动画)的介绍

4.1 增加或删除的功能

在Activity 中添加一下代码:@Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.main, menu);        return super.onCreateOptionsMenu(menu);    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        switch (item.getItemId())        {            case R.id.action_add:                myAdapter.addData(1);                break;            case R.id.action_remove:                myAdapter.removeData(1);                break;        }        return true;    }<?xml version="1.0" encoding="utf-8"?>

R.menu.main(在res 文件下创建menu文件夹下添加main.xml)代码 :

<menu xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:app="http://schemas.android.com/apk/res-auto"    tools:context="example.gmariotti.it.test21.TaylorActivity">    <item android:id="@+id/action_add"        android:title="ADD"        android:orderInCategory="100"        app:showAsAction="always" />    <item android:id="@+id/action_remove"        android:title="REMOVE"        android:orderInCategory="100"        app:showAsAction="always" /></menu>

在Adapter 中添加以下两个函数:

        /**         * 动态增加或删除条目         * @param position         */        public void addData(int position) {            mList.add(position, "add One");            notifyItemInserted(position);            notifyDataSetChanged();        }        public void removeData(int position) {            mList.remove(position);            notifyItemRemoved(position);            notifyDataSetChanged();        }

这里我们更新数据使用的不是notifyDataSetChanged() 而是notifyItemInsert()和notifyItemRemove() 否则没有动画效果(但这里还是加了notifyDataSetChanged,是因为动态添加多个item时,点击事件位置不对,调用了就不会有问题);
这是从其他优秀开发者借鉴的图片:

4.2 修改增删动画效果

系统为我们提供了默认实现类,借助默认的实现,当Item添加和移除的时候,添加动画效果很简单:

//设置增加或删除条目的动画  mRecyclerView.setItemAnimator( new DefaultItemAnimator());  

编辑RecyclerView 的点击事件

相信大家在使用ListView时已经习惯了设置点击事件,它给我们提供了封装好的OnItemClickListener,然而对于RecyclerView,很可惜并没有给我们提供任何的点击监听,但我们可以模仿自己添加监听方法,接下来我们在Adapter 中添加两个函数:

class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>{//...    public interface OnItemClickLitener    {        void onItemClick(int position);        void onItemLongClick(int position);    }    private OnItemClickLitener mOnItemClickLitener;    public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)    {        this.mOnItemClickLitener = mOnItemClickLitener;    }    @Override    public void onBindViewHolder(final MyViewHolder holder, final int position)    {        holder.textview.setText(mList.get(position));        // 如果设置了回调,则设置点击事件        if (mOnItemClickLitener != null)        {            holder.itemView.setOnClickListener(new OnClickListener()            {                @Override                public void onClick(View v)                {                    mOnItemClickLitener.onItemClick(position);                }            });            holder.itemView.setOnLongClickListener(new OnLongClickListener()            {                @Override                public boolean onLongClick(View v)                {                    mOnItemClickLitener.onItemLongClick(position);                    return false;                }            });        }    }//...}

正如以上所写,添加了自定义点击事件的监听接口,然后在onBindViewHolder 进行相应设置。

在activity 中代码实现:myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {            @Override            public void onClick1(int position) {                Toast.makeText(RecyclerviewAc.this,"点击了第"+position+"位置",Toast.LENGTH_SHORT).show();            }            @Override            public void onLongClick(int position) {                Toast.makeText(RecyclerviewAc.this,"长按了第"+position+"位置",Toast.LENGTH_SHORT).show();            }        });

这里就不上效果图了,点击效果很简单,一个提示而已。到这里RecyclerView的点击事件也基本结束。

结合MaterialRefreshLayout 构成流畅而优雅的刷新和加载更多

给大家推荐一个不错的刷新和加载控件,操作简单,配合RecyclerView一起使用,可满足大多数需求了。

这次总结就到这里,如果有什么建议或意见,欢迎留言!再次感谢两篇博文的参考。

源码地址

以上博文参考地址:(http://blog.csdn.net/skykingf/article/details/50827141)

[http://blog.csdn.net/lmj623565791/article/details/45059587]

0 0
原创粉丝点击