RecyclerView使用详解 各种布局

RecyclerView是support:recyclerview-v7中提供的控件,最低兼容到android 3.0版本。

官方介绍RecyclerView为在有限的窗口展现大量数据的控件。拥有类似功能的控件有ListView、GridView以及被Google遗弃的Gallery等,为毛已经有了它们,Google还推出RecyclerView呢,那就要说说RecyclerView所具有的一些优势了。

那RecyclerView到底有啥优势呢?总结起来六颗字:低耦合高类聚。RecyclerView已经标准化ViewHolder,我们自定义的ViewHoler需要继承 RecyclerView.ViewHolder,然后在构造方法中初始化控件,后面会有具体介绍。通过设置不同的LayoutManager,以及结合ItemDecoration , ItemAnimator,ItemTouchHelper,可以实现非常炫酷的效果,这些是ListView等控件难以企及的。

基本使用:

1.使用前需要在在gradle中添加依赖

 

implementation 'com.android.support:recyclerview-v7:27.0.2'

2.编写代码,首先我们需要在Xml中写RecyclerView的布局,

 
  1.  
    < android.support.v7.widget.RecyclerView
  2.  
    android:id= "@+id/recyclerView"
  3.  
    android:layout_width= "match_parent"
  4.  
    android:layout_height= "match_parent"/>

然后在activity中获取RecyclerView,并设置LayoutManager以及adapter

 

 
  1.  
    //通过findViewById拿到RecyclerView实例
  2.  
    mRecyclerView = findViewById(R.id.recyclerView);
  3.  
    //设置RecyclerView管理器
  4.  
    mRecyclerView.setLayoutManager( new LinearLayoutManager( this, LinearLayoutManager.VERTICAL, false));
  5.  
    //初始化适配器
  6.  
    mAdapter = new MyRecyclerViewAdapter(list);
  7.  
    //设置添加或删除item时的动画,这里使用默认动画
  8.  
    mRecyclerView.setItemAnimator( new DefaultItemAnimator());
  9.  
    //设置适配器
  10.  
    mRecyclerView.setAdapter(mAdapter);

下面是MyRecyclerViewAdapter的代码:

 

 

 

  1.  
    package com.sharejoys.recyclerviewdemo.actvity;
  2.  
     
  3.  
    import android.support.v7.widget.RecyclerView;
  4.  
    import android.view.LayoutInflater;
  5.  
    import android.view.View;
  6.  
    import android.view.ViewGroup;
  7.  
    import android.widget.TextView;
  8.  
     
  9.  
    import com.sharejoys.recyclerviewdemo.R;
  10.  
     
  11.  
    import java.util.List;
  12.  
     
  13.  
    /**
  14.  
    * Created by 青青-子衿 on 2018/1/15.
  15.  
    */
  16.  
     
  17.  
     
  18.  
    public class MyRecyclerViewAdapterextends RecyclerView. Adapter< MyAdapter. ViewHolder> {
  19.  
    private List list;
  20.  
     
  21.  
    public MyAdapter(List list) {
  22.  
    this.list = list;
  23.  
    }
  24.  
     
  25.  
    @Override
  26.  
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  27.  
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_base_use, parent, false);
  28.  
    MyAdapter.ViewHolder viewHolder = new MyAdapter.ViewHolder(view);
  29.  
    return viewHolder;
  30.  
    }
  31.  
     
  32.  
    @Override
  33.  
    public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) {
  34.  
    holder.mText.setText(list.get(position));
  35.  
    }
  36.  
     
  37.  
    @Override
  38.  
    public int getItemCount() {
  39.  
    return list.size();
  40.  
    }
  41.  
     
  42.  
    class ViewHolder extends RecyclerView. ViewHolder {
  43.  
    TextView mText;
  44.  
    ViewHolder(View itemView) {
  45.  
    super(itemView);
  46.  
    mText = itemView.findViewById(R.id.item_tx);
  47.  
    }
  48.  
    }
  49.  
    }

这里item_normal的布局也非常简单

 
  1.  
    xml version= "1.0" encoding= "utf-8" ?>
  2.  
    < LinearLayout
  3.  
    xmlns:android= "http://schemas.android.com/apk/res/android"
  4.  
    android:layout_width= "match_content"
  5.  
    android:layout_height= "wrap_content"
  6.  
    android:orientation= "vertical">
  7.  
     
  8.  
    < TextView
  9.  
    android:id= "@+id/item_tx"
  10.  
    android:layout_width= "match_content"
  11.  
    android:layout_height= "wrap_content"
  12.  
    android:gravity= "center"
  13.  
    android:padding= "10dp"
  14.  
    android:layout_gravity= "center_horizontal"
  15.  
    android:text= "Item"/>
  16.  
     
  17.  
    LinearLayout>

然后我们运行效果如下

RecyclerView使用详解 各种布局_第1张图片

从例子也可以看出来,RecyclerView的用法并不比ListView复杂,反而更灵活好用,它将数据、排列方式、数据的展示方式都分割开来,因此可定制型,自定义的形式也非常多,非常灵活。

 

 

 

设置横向布局:

 

 mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));

 

RecyclerView使用详解 各种布局_第2张图片

设置网格布局:

 

 

 mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));

RecyclerView使用详解 各种布局_第3张图片

设置瀑布流:

 mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));

RecyclerView使用详解 各种布局_第4张图片

如果第二个参数可以设置为横向的,则效果如下:

RecyclerView使用详解 各种布局_第5张图片

从以上可知,我们可以通过设置不同的管理器,实现不同的效果
LinearLayoutManager:以线性布局展示,可以设置横向和纵向
GridLayoutManager:以网格形式展示,类似GridView效果
StaggeredGridLayoutManager:以瀑布流形式的效果

RecyclerView条目之间默认没有分割线,那是否可以像ListView一样设置divider以及dividerHight搞一条分割线出来呢,答案是不可以的,google并没有提供这样的属性。但是谷歌为我们提供了可以定制的解决办法,那就是以下要说ItemDecoration

 

 

 

利用ItemDecoration实现条目分割线

ItemDecoration是谷歌定义的可用于画分割线的类, 是抽象的,需要我们自己去实现

 

 
  1.  
    /**
  2.  
    * An ItemDecoration allows the application to add a special drawing and layout offset
  3.  
    * to specific item views from the adapter's data set. This can be useful for drawing dividers
  4.  
    * between items, highlights, visual grouping boundaries and more.
  5.  
    *
  6.  
    *

    All ItemDecorations are drawn in the order they were added, before the item

  7.  
    * views (in {@link ItemDecoration#onDraw(Canvas, RecyclerView, RecyclerView.State) onDraw()}
  8.  
    * and after the items (in {@link ItemDecoration#onDrawOver(Canvas, RecyclerView,
  9.  
    * RecyclerView.State)}.

  10.  
    */
  11.  
    public abstract static class ItemDecoration {
  12.  
    public void onDraw(Canvas c, RecyclerView parent, State state) {
  13.  
    onDraw(c, parent);
  14.  
    }
  15.  
    @Deprecated
  16.  
    public void onDraw(Canvas c, RecyclerView parent) {
  17.  
    }
  18.  
     
  19.  
    public void onDrawOver(Canvas c, RecyclerView parent, State state) {
  20.  
    onDrawOver(c, parent);
  21.  
    }
  22.  
     
  23.  
    @Deprecated
  24.  
    public void onDrawOver(Canvas c, RecyclerView parent) {
  25.  
    }
  26.  
     
  27.  
     
  28.  
    @Deprecated
  29.  
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
  30.  
    outRect.set( 0, 0, 0, 0);
  31.  
    }
  32.  
     
  33.  
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
  34.  
    getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
  35.  
    parent);
  36.  
    }
  37.  
    }

当我们通过

mRecyclerView.addItemDecoration();

    onDraw: 该方法可以在RecyclerView的画布上画任何装饰,且是在 the item views 被绘制之前回调
    onDrawOver:该方法可以在RecyclerView的画布上画任何装饰,且是在 the item views 被绘制之后回调
    getItemOffsets :可以在该方法中为the item views添加偏移量

下面我们可以就通过继承ItemDecoration为RecyclerView添加分割线。
DividerItemDecoration的代码如下: 

 

 

 

 

 
  1.  
    package com.sharejoys.mvpdemo.ui.customview;
  2.  
     
  3.  
    import android.content.Context;
  4.  
    import android.content.res.TypedArray;
  5.  
    import android.graphics.Canvas;
  6.  
    import android.graphics.Rect;
  7.  
    import android.graphics.drawable.Drawable;
  8.  
    import android.support.annotation.IntDef;
  9.  
    import android.support.v4.view.ViewCompat;
  10.  
    import android.support.v7.widget.LinearLayoutManager;
  11.  
    import android.support.v7.widget.RecyclerView;
  12.  
    import android.view.View;
  13.  
     
  14.  
    /**
  15.  
    * Date: 2018/1/14
  16.  
    *
  17.  
    * @author 青青-子衿
  18.  
    * @since 1.0
  19.  
    */
  20.  
     
  21.  
    public class DividerItemDecoration extends RecyclerView. ItemDecoration {
  22.  
    @OrientationType
  23.  
    private int mOrientation = LinearLayoutManager.VERTICAL;
  24.  
    private Drawable mDivider;
  25.  
     
  26.  
    private int[] attrs = new int[]{
  27.  
    android.R.attr.listDivider
  28.  
    };
  29.  
     
  30.  
    public DividerItemDecoration(Context context, @OrientationType int orientation) {
  31.  
    TypedArray typedArray = context.obtainStyledAttributes(attrs);
  32.  
    mDivider = typedArray.getDrawable( 0);
  33.  
    typedArray.recycle();
  34.  
    setOrientation(orientation);
  35.  
    }
  36.  
     
  37.  
    private void setOrientation(@OrientationType int orientation) {
  38.  
    if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
  39.  
    throw new IllegalArgumentException( "传入的布局类型不合法");
  40.  
    }
  41.  
    this.mOrientation = orientation;
  42.  
    }
  43.  
     
  44.  
    @Override
  45.  
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
  46.  
    //调用这个绘制方法,RecyclerView会回调该绘制方法,需要我们自己去绘制条目的间隔线
  47.  
    if (mOrientation == LinearLayoutManager.VERTICAL) {
  48.  
    //垂直
  49.  
    drawVertical(c, parent);
  50.  
    } else {
  51.  
    //水平
  52.  
    drawHorizontal(c, parent);
  53.  
    }
  54.  
    }
  55.  
     
  56.  
    private void drawVertical(Canvas c, RecyclerView parent) {
  57.  
    // 画水平线
  58.  
    int left = parent.getPaddingLeft();
  59.  
    int right = parent.getWidth() - parent.getPaddingRight();
  60.  
    int childCount = parent.getChildCount();
  61.  
    for ( int i = 0; i < childCount; i++) {
  62.  
    View child = parent.getChildAt(i);
  63.  
     
  64.  
    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
  65.  
    int top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));
  66.  
    int bottom = top + mDivider.getIntrinsicHeight();
  67.  
    mDivider.setBounds(left, top, right, bottom);
  68.  
    mDivider.draw(c);
  69.  
    }
  70.  
    }
  71.  
     
  72.  
    private void drawHorizontal(Canvas c, RecyclerView parent) {
  73.  
    int top = parent.getPaddingTop();
  74.  
    int bottom = parent.getHeight() - parent.getPaddingBottom();
  75.  
    int childCount = parent.getChildCount();
  76.  
    for ( int i = 0; i < childCount; i++) {
  77.  
    View child = parent.getChildAt(i);
  78.  
     
  79.  
    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
  80.  
    int left = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));
  81.  
    int right = left + mDivider.getIntrinsicHeight();
  82.  
    mDivider.setBounds(left, top, right, bottom);
  83.  
    mDivider.draw(c);
  84.  
    }
  85.  
    }
  86.  
     
  87.  
    @Override
  88.  
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
  89.  
    //获得条目的偏移量(所有的条目都会回调一次该方法)
  90.  
    if (mOrientation == LinearLayoutManager.VERTICAL) {
  91.  
    //垂直
  92.  
    outRect.set( 0, 0, 0, mDivider.getIntrinsicHeight());
  93.  
    } else {
  94.  
    //水平
  95.  
    outRect.set( 0, 0, mDivider.getIntrinsicWidth(), 0);
  96.  
    }
  97.  
    }
  98.  
     
  99.  
    @IntDef({LinearLayoutManager.VERTICAL, LinearLayoutManager.HORIZONTAL})
  100.  
    public @interface OrientationType {
  101.  
    }
  102.  
    }

然后在activity设置水平方向

 

 

 

  1.  
    mRecyclerView.setLayoutManager( new LinearLayoutManager( this, LinearLayoutManager.VERTICAL, false);
  2.  
    mRecyclerView.addItemDecoration( new DividerItemDecoration( this, LinearLayoutManager.VERTICAL));

RecyclerView使用详解 各种布局_第6张图片

竖直方向:

 

 

 
  1.  
    mRecyclerView.setLayoutManager( new LinearLayoutManager( this, LinearLayoutManager.HORIZONAL, false);
  2.  
    mRecyclerView.addItemDecoration( new DividerItemDecoration( this, LinearLayoutManager.HORIZONAL))

RecyclerView使用详解 各种布局_第7张图片

这里的分割线是默认的,我们可以在主题中去设置分割线的颜色

 
  1.  
  2.  
    < style name= "AppTheme" parent= "Theme.AppCompat.Light.DarkActionBar">
  3.  
  4.  
    < item name= "colorPrimary">@color/colorPrimaryitem>
  5.  
    < item name= "colorPrimaryDark">@color/colorPrimaryDarkitem>
  6.  
    < item name= "colorAccent">@color/colorAccentitem>
  7.  
    < item name= "android:listDivider">@drawable/bg_recyclerview_divideritem>
  8.  
    style>

bg_recyclerview_divider.xml

 

 

 

  1.  
    xml version= "1.0" encoding= "utf-8" ?>
  2.  
    < shape xmlns:android= "http://schemas.android.com/apk/res/android"
  3.  
    android:shape= "rectangle">
  4.  
     
  5.  
    < gradient
  6.  
    android:centerColor= "#ff00ff00"
  7.  
    android:endColor= "#ff0000ff"
  8.  
    android:startColor= "#ffff0000"
  9.  
    android:type= "linear"/>
  10.  
     
  11.  
    < size
  12.  
    android:width= "10dp"
  13.  
    android:height= "10dp"/>
  14.  
     
  15.  
    shape>

运行后效果如下

RecyclerView使用详解 各种布局_第8张图片

以上的分割线只适用在LinearLayoutManager的相关布局中。
对于GridLayoutManager布局是不适用的。需要我们单独写一个。

 

以下是对于GridLayoutManager布局的分割线代码

 

 
  1.  
    package com.sharejoys.recyclerviewdemo.view;
  2.  
     
  3.  
    import android.content.Context;
  4.  
    import android.content.res.TypedArray;
  5.  
    import android.graphics.Canvas;
  6.  
    import android.graphics.Rect;
  7.  
    import android.graphics.drawable.Drawable;
  8.  
    import android.support.v7.widget.GridLayoutManager;
  9.  
    import android.support.v7.widget.RecyclerView;
  10.  
    import android.view.View;
  11.  
     
  12.  
    /**
  13.  
    * Date: 2018/1/14
  14.  
    *
  15.  
    * @author 青青-子衿
  16.  
    * @since 1.0
  17.  
    */
  18.  
     
  19.  
    public class DividerGridViewItemDecoration extends RecyclerView. ItemDecoration {
  20.  
    private Drawable mDivider;
  21.  
    private int[] attrs = new int[]{
  22.  
    android.R.attr.listDivider};
  23.  
     
  24.  
    public DividerGridViewItemDecoration(Context context) {
  25.  
    TypedArray typedArray = context.obtainStyledAttributes(attrs);
  26.  
    mDivider = typedArray.getDrawable( 0);
  27.  
    typedArray.recycle();
  28.  
    }
  29.  
     
  30.  
    @Override
  31.  
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
  32.  
    drawVertical(c, parent);
  33.  
    drawHorizontal(c, parent);
  34.  
    }
  35.  
     
  36.  
    private void drawVertical(Canvas c, RecyclerView parent) {
  37.  
    //绘制垂直间隔线(垂直的矩形)
  38.  
    int childCount = parent.getChildCount();
  39.  
    for ( int i = 0; i < childCount; i++) {
  40.  
    View child = parent.getChildAt(i);
  41.  
    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
  42.  
    int left = child.getRight() + params.rightMargin;
  43.  
    int right = left + mDivider.getIntrinsicWidth();
  44.  
    int top = child.getTop() - params.topMargin;
  45.  
    int bottom = child.getBottom() + params.bottomMargin;
  46.  
     
  47.  
    mDivider.setBounds(left, top, right, bottom);
  48.  
    mDivider.draw(c);
  49.  
    }
  50.  
    }
  51.  
     
  52.  
    private void drawHorizontal(Canvas c, RecyclerView parent) {
  53.  
    //绘制水平分割线
  54.  
    int childCount = parent.getChildCount();
  55.  
    for ( int i = 0; i < childCount; i++) {
  56.  
    View child = parent.getChildAt(i);
  57.  
    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
  58.  
    int left = child.getLeft() - params.leftMargin;
  59.  
    int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth();
  60.  
    int top = child.getBottom() + params.bottomMargin;
  61.  
    int bottom = top + mDivider.getIntrinsicHeight();
  62.  
     
  63.  
    mDivider.setBounds(left, top, right, bottom);
  64.  
    mDivider.draw(c);
  65.  
    }
  66.  
    }
  67.  
     
  68.  
    @Override
  69.  
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
  70.  
    // 四个方向的偏移值
  71.  
    int right = mDivider.getIntrinsicWidth();
  72.  
    int bottom = mDivider.getIntrinsicHeight();
  73.  
     
  74.  
    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
  75.  
    int itemPosition = params.getViewAdapterPosition();
  76.  
    if (isLastColum(itemPosition, parent)) {
  77.  
    right = 0;
  78.  
    }
  79.  
     
  80.  
    if (isLastRow(itemPosition, parent)) {
  81.  
    bottom = 0;
  82.  
    }
  83.  
    outRect.set( 0, 0, right, bottom);
  84.  
    }
  85.  
     
  86.  
    /**
  87.  
    * 是否最后一行
  88.  
    */
  89.  
    private boolean isLastRow( int itemPosition, RecyclerView parent) {
  90.  
    int spanCount = getSpanCount(parent);
  91.  
    if (spanCount != - 1) {
  92.  
    int childCount = parent.getAdapter().getItemCount();
  93.  
    int lastRowCount = childCount % spanCount;
  94.  
    //最后一行的数量小于spanCount
  95.  
    if (lastRowCount == 0 || lastRowCount < spanCount) {
  96.  
    return true;
  97.  
    }
  98.  
    }
  99.  
     
  100.  
    return false;
  101.  
    }
  102.  
     
  103.  
     
  104.  
    /**
  105.  
    * 根据parent获取到列数
  106.  
    */
  107.  
    private int getSpanCount(RecyclerView parent) {
  108.  
    RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
  109.  
    if (layoutManager instanceof GridLayoutManager) {
  110.  
    GridLayoutManager lm = (GridLayoutManager) layoutManager;
  111.  
    int spanCount = lm.getSpanCount();
  112.  
    return spanCount;
  113.  
    }
  114.  
    return - 1;
  115.  
    }
  116.  
     
  117.  
    /**
  118.  
    * 判断是否是最后一列
  119.  
    */
  120.  
    private boolean isLastColum( int itemPosition, RecyclerView parent) {
  121.  
    int spanCount = getSpanCount(parent);
  122.  
    if (spanCount != - 1) {
  123.  
    if ((itemPosition + 1) % spanCount == 0) {
  124.  
    return true;
  125.  
    }
  126.  
    }
  127.  
    return false;
  128.  
    }
  129.  
    }

我们在activity中使用该分割线

 

 

 
  1.  
    mRecyclerView.setLayoutManager( new GridLayoutManager( this, 3));
  2.  
    mRecyclerView.addItemDecoration( new DividerGridViewItemDecoration( this));

RecyclerView使用详解 各种布局_第9张图片

点击事件


RecyclerView并没有像ListView的那样可以设置点击事件以及长按点击事件,这个需要我们可以在adapter中去设置回调的方式实现,具体代码如下:
MyRecyclerViewAdapter的代码如下:

 

 

 

  1.  
    package com.sharejoys.recyclerviewdemo.actvity;
  2.  
     
  3.  
    import android.support.v7.widget.RecyclerView;
  4.  
    import android.view.LayoutInflater;
  5.  
    import android.view.View;
  6.  
    import android.view.ViewGroup;
  7.  
    import android.widget.TextView;
  8.  
     
  9.  
    import com.sharejoys.recyclerviewdemo.R;
  10.  
     
  11.  
    import java.util.List;
  12.  
     
  13.  
    /**
  14.  
    * Created by 青青-子衿 on 2018/1/15.
  15.  
    */
  16.  
     
  17.  
     
  18.  
    public class MyRecyclerViewAdapter extends RecyclerView. Adapter< MyRecyclerViewAdapter. ViewHolder> {
  19.  
    private List list;
  20.  
    private OnItemClickListener onItemClickListener;
  21.  
    private OnItemLongClickListener onItemLongClickListener;
  22.  
     
  23.  
    /**
  24.  
    * 设置点击事件
  25.  
    */
  26.  
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
  27.  
    this.onItemClickListener = onItemClickListener;
  28.  
    }
  29.  
     
  30.  
    /**
  31.  
    * 设置长按点击事件
  32.  
    */
  33.  
    public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
  34.  
    this.onItemLongClickListener = onItemLongClickListener;
  35.  
    }
  36.  
     
  37.  
    public MyRecyclerViewAdapter(List list) {
  38.  
    this.list = list;
  39.  
    }
  40.  
     
  41.  
    @Override
  42.  
    public MyRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  43.  
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_base_use, parent, false);
  44.  
    MyRecyclerViewAdapter.ViewHolder viewHolder = new MyRecyclerViewAdapter.ViewHolder(view);
  45.  
    return viewHolder;
  46.  
    }
  47.  
     
  48.  
    @Override
  49.  
    public void onBindViewHolder(MyRecyclerViewAdapter.ViewHolder holder, int position) {
  50.  
    holder.mText.setText(list.get(position));
  51.  
    int adapterPosition = holder.getAdapterPosition();
  52.  
    if (onItemClickListener != null) {
  53.  
    holder.itemView.setOnClickListener( new MyOnClickListener(position, list.get(adapterPosition)));
  54.  
    }
  55.  
    if (onItemLongClickListener != null) {
  56.  
    holder.itemView.setOnLongClickListener( new MyOnLongClickListener(position, list.get(adapterPosition)));
  57.  
    }
  58.  
    }
  59.  
     
  60.  
    @Override
  61.  
    public int getItemCount() {
  62.  
    return list.size();
  63.  
    }
  64.  
     
  65.  
    class ViewHolder extends RecyclerView. ViewHolder {
  66.  
    TextView mText;
  67.  
     
  68.  
    ViewHolder(View itemView) {
  69.  
    super(itemView);
  70.  
    mText = itemView.findViewById(R.id.item_tx);
  71.  
    }
  72.  
    }
  73.  
     
  74.  
    private class MyOnLongClickListener implements View. OnLongClickListener {
  75.  
    private int position;
  76.  
    private String data;
  77.  
     
  78.  
    public MyOnLongClickListener( int position, String data) {
  79.  
    this.position = position;
  80.  
    this.data = data;
  81.  
    }
  82.  
     
  83.  
    @Override
  84.  
    public boolean onLongClick(View v) {
  85.  
    onItemLongClickListener.onItemLongClick(v, position, data);
  86.  
    return true;
  87.  
    }
  88.  
    }
  89.  
     
  90.  
    private class MyOnClickListener implements View. OnClickListener {
  91.  
    private int position;
  92.  
    private String data;
  93.  
     
  94.  
    public MyOnClickListener( int position, String data) {
  95.  
    this.position = position;
  96.  
    this.data = data;
  97.  
    }
  98.  
     
  99.  
    @Override
  100.  
    public void onClick(View v) {
  101.  
    onItemClickListener.onItemClick(v, position, data);
  102.  
    }
  103.  
    }
  104.  
     
  105.  
     
  106.  
    public interface OnItemClickListener {
  107.  
    void onItemClick(View view, int position, String data);
  108.  
    }
  109.  
     
  110.  
    public interface OnItemLongClickListener {
  111.  
    void onItemLongClick(View view, int position, String data);
  112.  
    }
  113.  
     
  114.  
    }
 

activity中设置监听:

 

 

 

  1.  
    mAdapter.setOnItemClickListener( new MyRecyclerViewAdapter.OnItemClickListener() {
  2.  
    @Override
  3.  
    public void onItemClick(View view, int position, String data) {
  4.  
    Toast.makeText(MainActivity. this, "您点击了: " + data, Toast.LENGTH_SHORT).show();
  5.  
    }
  6.  
    });
  7.  
    mAdapter.setOnItemLongClickListener( new MyRecyclerViewAdapter.OnItemLongClickListener() {
  8.  
    @Override
  9.  
    public void onItemLongClick(View view, int position, String data) {
  10.  
    Toast.makeText(MainActivity. this, "您长按点击了: " + data, Toast.LENGTH_SHORT).show();
  11.  
    }
  12.  
    });

运行后效果如下:

RecyclerView使用详解 各种布局_第10张图片RecyclerView使用详解 各种布局_第11张图片

ItemAnimator

 

我们可以为RecyclerView设置增加和删除动画,这里我们可以使用默认动画
 

 
  1.  
    //设置添加或删除item时的动画,这里使用默认动画
  2.  
    mRecyclerView.setItemAnimator( new DefaultItemAnimator());

然后在Adapter中增加删除和添加数据的方法

 

 

 

  1.  
    /**
  2.  
    * 插入一条数据
  3.  
    *
  4.  
    * @param index 下标
  5.  
    * @param s 数据
  6.  
    */
  7.  
    public void addItem( int index, String s) {
  8.  
    list.add(index, s);
  9.  
    notifyItemInserted(index);
  10.  
    }
  11.  
     
  12.  
    /**
  13.  
    * 删除一条数据
  14.  
    *
  15.  
    * @param index 下标
  16.  
    */
  17.  
    public void deleteItem( int index) {
  18.  
    list.remove(index);
  19.  
    notifyItemRemoved(index);
  20.  
    }

activty调用删除和添加方法后效果如下

 

 

RecycleView还有一些其他用法,比如结合ItemTouchHelper实现item的拖拽效果,可以自定义增加header和footer(类似Listview)

作者地址:https://blog.csdn.net/tuike/article/details/79064750

你可能感兴趣的:(RecyclerView使用详解 各种布局)