RecyclerView的那点事儿

举报
小工匠 发表于 2021/09/10 01:40:50 2021/09/10
【摘要】 RecyclerView 控件简介 ListView的升级版LinearLayoutManagerGridLayoutManagerStaggeredGridLayoutManager定制Item动画...

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'
  
 
  • 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;
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
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;
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

绘制列表项之间的分隔线

这里写图片描述

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

}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

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


}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117

完成使用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);


    }


}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

效果图

这里写图片描述

定制个性化分隔条

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>
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

主题中设置

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

瀑布流

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




    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

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>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

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>
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

效果图

这里写图片描述

动画效果

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

notifyItemRemoved(position)

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

    }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

notifyItemInserted(positionToAdd)

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

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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

        }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

做完这些事情,我们就可以在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();

            }
        });
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

完整代码如下:

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

            }
        });
    }


}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

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


}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160

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

原理:
为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);
    }
  
 
  • 1
  • 2
  • 3
  • 4

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

  private OnRecyclerViewItemClickListener mOnItemClickListener = null;
  
 
  • 1

在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;
    }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

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

意上面调用接口的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]);
    }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

 public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }
  
 
  • 1
  • 2
  • 3

以上所有步骤都发生在自定义的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();
            }
        });
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

~

RecyclerView添加Header

。。。。。。

文章来源: artisan.blog.csdn.net,作者:小小工匠,版权归原作者所有,如需转载,请联系作者。

原文链接:artisan.blog.csdn.net/article/details/51031318

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。