前言:人在无端微笑时,不是百无聊赖,就是痛苦难当。有些笑容的背后是咬紧牙关的灵魂。     ——看见 -柴静

一、概述

1.1 RecyclerView是什么?

  自Android5.0之后Google推出了新的列表控件RecyclerView,代替了经典的ListView,是一个强大的滑动组件,拥有item的复用回收功能,更加高级和灵活。此组件是一个用于显示庞大数据集的容器,可通过保持有限数量的视图进行非常有效的滚动操作。如果您有数据集合,其中的元素将因用户操作或者网络事件而发生改变,建议使用RecyclerView。

官方对它的介绍:

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

大意:为大量数据集提供一个有限的展示窗口的灵活视图。列表是app非常常见的,怎么展示大量的数据是个技术活,特别是在手机捉襟见肘的内存中显得尤为重要,怎么在微小的内存中显示大量的数据?

RecyclerView通过提供下列功能来简化庞大数据集的显示与处理:

  • 用于项目定位的布局管理器;
  • 用于通用项目操作(例如删除或添加Item)的默认动画;
  • 自身的强大回收复用机制。

如果要使用RecyclerView组件,必须指定一个Adapter和一个LayoutManager。通过继承RecyclerView.Adapter的方式可以自定义一个Adapter。实现Adapter的详情将取决于数据data集合的具体信息以及视图view的类型。
在这里插入图片描述
LayoutManager决定RecyclerView内各项item的位置并决定何时重新使用用户已不可见的item。
如果要重新使用一个item,LayoutManager可能会要求Adapter以数据集合中的另一组数据替换item的内容。以此方式重复使用视图将可避免创建不必要的视图或执行非常耗的findViewById,从而改善性能。

Adapter适配器的功能是为数据源中的每一个Item创建一个视图,并为他们设置相应的数据,当之前的Item不可见时,以新的Item进行替换。

RecyclerView默认情况下,当增加或者删除Item时,带有动画效果。如果要定制某些其他效果的动画,需要扩展RecyclerView.ItemAnimator类,并使用RecyclerView.setItemAnimator设置所定制的动画。

1.2 RecyclerView的优点

官方介绍RecyclerView是ListView的升级版,RecyclerView相对ListView的优点如下:

  • 1.RecyclerView封装了ViewHolder的回收复用,就是说RecyclerView标准化了ViewHolder,编写的Adapter面向的是ViewHolder不再是View,复用逻辑被封装,写起来更简单。ListView中的复用逻辑需要自己手动添加contentView==null,convertView.setTag(holder),holder=(ViewHolder)convertView.getTag()的繁琐操作;
  • 2.设置布局管理器LayoutManager控制item的布局样式,横向、竖向、网格布局、瀑布流布局等;普通列表使用LinearLayoutManager,网格布局管理器GridLayoutManager,瀑布流布局管理器StaggeredGridLayoutManager;
  • 3.提供了一种插拔式的体验,高度解耦,异常灵活,针对一个item的显示RecyclerView专门抽出响应的类来控制,拓展性非常强;
  • 4.可以设置Item的分隔样式,比如分割线,通过继承RecyclerView的ItemDecoration针对自己的业务逻辑进行处理;
  • 5.通过ItemAnimator可以控制item的增删动画。

但是关于RecyclerView的item的相关点击事件需要自己高度自定义,不像ListView那样item点击事件能快速响应。

以下是RecyclerView内部的几个重要类,简单了解下,后面的文章都有详细涉及相关的内容。

类名作用
RecyclerView.Adapter为每一项item创建视图
RecyclerView.ViewHolder承载item视图的子布局
RecyclerView.LayoutManager负责item视图的布局显示管理
RecyclerView.Recycler负责处理item的回收复用,即缓存
RecyclerView.ItemDecoration给每一项item视图添加子View,如分割线
RecyclerView.ItemAnimator负责处理数据添加或者删除时的动画效果

二、简单使用

2.1 添加依赖

RecyclerView是support-v7的组件,我们要在build.gradle文件中加入RecyclerView的依赖:
在这里插入图片描述
添加RecyclerView的依赖:

implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha01'

我们先来实现简单的列表效果,如下图:

2.2 布局文件引入RecyclerView

在Activity的布局文件中加入RecyclerView控件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

然后我们在Activity中通过findViewById()查找到该控件

RecyclerView recyclerView = findViewById(R.id.recyclerView);

2.3 设置布局管理器LayoutManager

RecyclerView能支持各种各样的布局效果,其关键核心在 RecyclerView.LayoutManager类中,RecyclerView的过程要比ListView的过程多一个setLayoutManager()的步骤,它是控制item最终的展示效果;LayoutManager负责RecyclerView的布局,包含了ItemView的获取和回收。下面会讲解

 //创建布局管理器-线性布局
 LinearLayoutManager manager = new LinearLayoutManager(this);
 //设置管理器的水平方向,RecyclerView.VERTICAL垂直方向,RecyclerView.HORIZONTAL水平方向
 manager.setOrientation(RecyclerView.VERTICAL);//RecyclerView.HORIZONTAL
 //设置布局布局管理器到recyclerView
 recyclerView.setLayoutManager(manager);

2.4 适配器Adapter

Adapter适配器的功能是为数据集合中的每一个Item创建一个ViewHolder,并为他们设置相应的数据,当之前的Item不可见时,以新的Item进行替换。Adapter其实就是为RecyclerView和数据绑定起来,将数据设置到具体的item中,这里的Adapter必需要继承自RecyclerView.Adapter<RecyclerView.ViewHolder>,并且最少重写其中的三个方法:

  • onCreateViewHolder(ViewGroup parent, int viewType):用于创建ViewHolder,通过ViewHolder承载视图中的元素,会为每一个item创建一个view,封装到ViewHolder中;viewType:用于区分不同itemView的类型;
  • onBindViewHolder(ViewHolder holder, int position): 将指定位置的数据和视图绑定起来,适配渲染数据到View中。ViewHolder:就是上面返回的holder,里面包含了item的View,通过他能获取holder里面的控件,然后设置数据;position:表示item的位置;
  • getItemCount():  指定RecyclerView有多少个Item。

这里adapter我们将数据和上下文通过构造函数带进来,实现上面的三个方法,adapter如下:

public class LinearVerticalAdapter extends RecyclerView.Adapter {
    public LinearVerticalAdapter(Context context, List<String> stringList) {
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    }

    @Override
    public int getItemCount() {
        return 0;
    }
}

这里RecyclerView的adapter和ListView的adapter有点不同的是RecyclerView把ListView的getView()方法拆分为绑定View的 onCreateViewHolder()和绑定数据的onBindViewHolder()

2.5 创建ViewHolder

接下来创建一个ViewHolder,ViewHolder就是为了保存每一个item的视图控件元素,它需要使用到item的视图,我们这里先创建item的布局文件 item_linear.xml

<?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:layout_marginTop="10dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#e7e7e7"
        android:paddingLeft="12dp"
        android:textColor="#3175ff"
        android:paddingTop="12dp"
        android:paddingBottom="12dp"
        android:text="item"
        android:textSize="16sp" />
</LinearLayout>

里面只是简单的TextView,我们先创建ViewHolder,它需要继承自RecyclerView.ViewHolder,ViewHolder主要作用是将item中的控件以变量的形式保存起来,方便后面的数据绑定;
ViewHolder.java

  public class ViewHolder extends RecyclerView.ViewHolder {
        //控件变量
        TextView mTv_name;
        
        ViewHolder(@NonNull View itemView) {
            super(itemView);
            mTv_name = itemView.findViewById(R.id.tv_name);
            mTv_name.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext, mTv_name.getText().toString(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

创建ViewHolder时,通过构造方法传入itemView,复写super(itemView)方法,将控件TextView从itemView里面取出,保存在mTv_name常量中,这样就能通过holder实例使用到控件。

2.6 Adapter使用ViewHolder

创建ViewHolder后就要使用它填充好Adapter的函数,首先是onCreateViewHolder()

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_recyclerview, parent, false));
    }

每一个item的创建都会调用一次onCreateViewHolder(),每次调用一次onCreateViewHolder()都会创建一个ViewHolder,每一个item inflater一个view,存入ViewHolder中,返回ViewHolder实例。

2.7 Adapter绑定数据

然后在onBindViewHolder()中,将ViewHolder与数据绑定起来;

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    ViewHolder viewHolder = (ViewHolder) holder;
    viewHolder.mTv_name.setText(mData.get(position));
}

每一个item都会走onBindViewHolder()方法,正是这个方法将数据与空件绑定起来,通过holder获取相关的Item控件,然后就可以对这些控件进行你需要的操作,比如点击事件,设置相关数据等。

最后在getItemCount()返回数据的个数;

@Override
public int getItemCount() {
    return mData.size();
}

到这里,完整的Adapter就实现了,如下代码:
LinearVerticalAdapter.java

public class LinearVerticalAdapter extends RecyclerView.Adapter {
    private Context mContext;
    private List<String> mData;

    //1.构造方法带入相关参数
    public LinearVerticalAdapter(Context context, List<String> stringList) {
        this.mContext = context;
        this.mData = stringList;
    }

    //2.用于得到ViewHolder,通过ViewHolder承载视图中的元素,会为每一个item inflate出一个view,封装到ViewHolder中
    //viewType:区分不同item的类型
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_recyclerview, parent, false));
    }

    //3.将指定位置的数据和视图绑定起来,适配渲染数据到View中,因为这里ViewHolder,里面包含了item的View
    //holder: 上面创建的ViewHolder,用于查找holder里面的控件,设置数据
    //position:item的位置
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ViewHolder viewHolder = (ViewHolder) holder;
        viewHolder.mTv_name.setText(mData.get(position));
    }

    //4.指定RecyclerView有多少个Item
    @Override
    public int getItemCount() {
        return mData.size();
    }
}

2.8 填充数据并关联适配器

最后创建模拟数据,填充到Adapter中,将Adapter设置给RecyclerView,这就基本实现了简单的RecyclerView列表功能;

 List<String> stringList = new ArrayList<>();
 for (int i = 0; i < 50; i++) {
     stringList.add("第 " + i + " 个item");
 }

构造adapter同过RecyclerView的setAdapter()方法设置到RecyclerView中,这样adapter才能与RecyclerView联系起来:

LinearVerticalAdapter adapter = new LinearVerticalAdapter(this, stringList);
recyclerView.setAdapter(adapter);//设置适配器给列表

Activity的完整代码如下:(源码地址在最后给出)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //1.查找控件
    RecyclerView recyclerView = findViewById(R.id.recyclerView);

    //2.创建布局管理器-线性布局
    LinearLayoutManager manager = new LinearLayoutManager(this);
    //设置管理器的水平方向,RecyclerView.VERTICAL垂直方向,RecyclerView.HORIZONTAL水平方向
    manager.setOrientation(RecyclerView.VERTICAL);//RecyclerView.HORIZONTAL
    //设置布局布局管理器到recyclerView
    recyclerView.setLayoutManager(manager);

    //3.设置数据
    List<String> stringList = new ArrayList<>();
    for (int i = 0; i < 50; i++) {
        stringList.add("第 " + i + " 个item");
    }

    //4.数据适配器
    LinearVerticalAdapter adapter = new LinearVerticalAdapter(this, stringList);
    //设置适配器到recyclerView
    recyclerView.setAdapter(adapter);
}

三、LayoutManager布局管理器

  前面提到,RecyclerView能支持各种各样的效果,主要是因为LayoutManager布局管理器用于控制RecyclerView的最终展示效果。

它决定RecyclerView内各项item的位置并决定item何时回收复用。如果要重新使用(或者重复使用)一个item,LayoutManager可能会要求Adapter以数据集合中的另一组数据替换item的内容。以此方式重复使用视图将可避免创建不必要的视图或执行非常耗的findViewById,从而改善性能。RecyclerView提供了三终常用的布局管理器:

  • LinearLayoutManager      以列表的方式展示item,有水平方向RecyclerView.HORIZONTAL和垂直方向RecyclerView.VERTICAL;
  • GridLayoutManager       以网格的方式展示item,有水平方向和垂直方向;
  • StaggeredGridLayoutManager   以瀑布流的方式展示item,有水平方向和垂直方向。

如果你想要达到自己自定义的效果,则应该去继承LayoutManager,重写相关的方法,而不是去改造RecyclerView,相关效果和相关API我们在下一篇文章展示。(源码地址在文章最后给出)

3.1 LinearLayoutManager

我们可以通过LayoutManager设置RecyclerView的列表方向是垂直方向还是水平方向,默认是垂直方向:

  • RecyclerView.VERTICAL     垂直方向;
  • RecyclerView.HORIZONTAL  水平方向。

其实只需要在LayoutManager中通过setOrientation()设置方向就可以了,也可以在构造方法中直接声明方向,这里以线性布局为例,提供了可用的两种构造方法,

  • LinearLayoutManager(Context context)   普通构造方法,默认是RecyclerView.VERTICAL垂直方向;
  • LinearLayoutManager(Context context, int orientation, boolean reverseLayout)   orientation表示线性方向,值为VERTICAL和HORIZONTAL,reverseLayout表示是否逆向展示,true表示逆向展示,false表示非逆向展示。

逆向展示的意思是在结束处开始布局,即在第一个item在列表最下面,最后一个item在最上面,从下面开始类增,具体可以自行试一试,基于上面的列子,我们将布局管理器方向设置为水平方向,为了方便效果,将item的宽高调整了一下,

manager.setOrientation(RecyclerView.HORIZONTAL)

效果如下:

3.2 GridLayoutManager

GridLayoutManager的主要作用是将item用于网格摆放,实现网格的布局效果,RecyclerView的布局样式主要是由布局管理器来控制的,我们只需要改下LayoutManager这块的代码就可以了,先来看看GridLayoutManager的构造方法:

  • GridLayoutManager(Context context, int spanCount)  默认线性方向为垂直方向,spanCount表示网格列数(垂直方向表示网格列数,水平方向表示网格行数);
  • GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout)   可指定线性方向和布局方向,spanCount表示列数(同上),orientation表示线性方向,reverseLayout表示是否从结束开始布局。
  	//1.查找控件
	RecyclerView recyclerView = findViewById(R.id.recyclerView);

    //2.创建布局管理器,列数为3,垂直方向
    GridLayoutManager manager = new GridLayoutManager(this, 3, RecyclerView.VERTICAL, false);
    //设置布局布局管理器到recyclerView
    recyclerView.setLayoutManager(manager);

    //3.设置数据
    List<String> stringList = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
        stringList.add("第 " + i + " 个item");
    }

    //4.数据适配器
    GridAdapter adapter = new GridAdapter(this, stringList);
    //设置适配器到recyclerView
    recyclerView.setAdapter(adapter);

效果如下左图,同时可以将线性方向设置为水平方向,如下右图:

//行数为3,水平方向
GridLayoutManager manager = new GridLayoutManager(this, 3, RecyclerView.HORIZONTAL, false);

3.3 StaggeredGridLayoutManager

StaggeredGridLayoutManager是瀑布流管理器,主要用来瀑布流效果,它只有一个构造方法

  • StaggeredGridLayoutManager(int spanCount, int orientation)    orientation表示线性方向,HORIZONTAL表示水平方向,VERTICAL表示垂直方向,spanCount表示垂直时是列数,水平方向时是行数。

那么我们把LayoutManager改为StaggeredGridLayoutManager,设置列数为3,垂直方向,

StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3, RecyclerView.VERTICAL)

注意,如果item的高度或者宽度不变的话,效果和网格布局的效果一样的,如下图,没有改变高度的瀑布流效果:

那么在垂直方向分别时,我们手动改变item的高度,在水平方向分布时,我们就改变item的宽度,这样就可以看到瀑布流的效果了,这只是模拟瀑布流的效果,具体还需要根据实际业务操作;在adapter定义了一个获取高度或者宽度的方法,根据position返回300,400,200三个数值。

  private int getRandom(int position) {
        if (position % 3 == 0) {//第一排
            return 300;
        } else if (position % 3 == 1) {//第二排
            return 400;
        } else {
            return 200;
        }
    }

然后在onBindViewHolder()方法中根据传入的线性mLinear来设置宽度或者宽度

   ViewGroup.LayoutParams layoutParams = viewHolder.mTv_name.getLayoutParams();
    if (mLinear == RecyclerView.VERTICAL) {//垂直方向,随机高度
        layoutParams.height = getRandom(position);
    } else if (mLinear == RecyclerView.HORIZONTAL) {//水平方向,随机宽度
        layoutParams.width = getRandom(position);
    }
    viewHolder.mTv_name.setLayoutParams(layoutParams);//设置控件的参数

改写后的效果如下:左图为垂直方向,有图为水平方向

下面贴出瀑布流的代码:StaggeredGridActivity.java

public class StaggeredGridActivity extends AppCompatActivity implements View.OnClickListener {

    private RecyclerView mRecyclerView;
    private List<String> mStringList;
    private StaggeredGridLayoutManager mManager;
    private StaggeredGridAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_grid_recyclerview);
        //1.查找控件
        Button btn_vertical = findViewById(R.id.btn_vertical);
        btn_vertical.setOnClickListener(this);
        findViewById(R.id.btn_horizontal).setOnClickListener(this);
        mRecyclerView = findViewById(R.id.recyclerView);

        //3.设置数据
        mStringList = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            mStringList.add("第 " + i + " 个item");
        }

        //4.数据适配器
        mAdapter = new StaggeredGridAdapter(this, mStringList);
        btn_vertical.performClick();
    }

    @Override
    public void onClick(View v) {
        //2.创建布局管理器
        switch (v.getId()) {
            case R.id.btn_vertical://垂直方向,列数为3
                mManager = new StaggeredGridLayoutManager(3, RecyclerView.VERTICAL);
                mAdapter.setLinear(RecyclerView.VERTICAL);
                break;
            case R.id.btn_horizontal://水平方向,行数为3
                mManager = new StaggeredGridLayoutManager(3, RecyclerView.HORIZONTAL);
                mAdapter.setLinear(RecyclerView.HORIZONTAL);
                break;
        }

        //设置布局布局管理器到recyclerView
        mRecyclerView.setLayoutManager(mManager);
        //设置适配器到recyclerView
        mRecyclerView.setAdapter(mAdapter);
    }
}

瀑布流适配器代码:StaggeredGridAdapter.java

public class StaggeredGridAdapter extends RecyclerView.Adapter {
    private Context mContext;
    private List<String> mData;
    private int mLinear;//线性方向

    public StaggeredGridAdapter(Context context, List<String> stringList) {
        this.mContext = context;
        this.mData = stringList;
    }

    //用于得到ViewHolder,通过ViewHolder承载视图中的元素,会为每一个item inflate出一个view,封装到ViewHolder中
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_grid, parent, false));
    }

    //将指定位置的数据和视图绑定起来,适配渲染数据到View中,因为这里ViewHolder,里面包含了item的View
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ViewHolder viewHolder = (ViewHolder) holder;
        viewHolder.mTv_name.setText(mData.get(position));

        ViewGroup.LayoutParams layoutParams = viewHolder.mTv_name.getLayoutParams();
        if (mLinear == RecyclerView.VERTICAL) {//垂直方向,随机高度
            layoutParams.height = getRandom(position);
        } else if (mLinear == RecyclerView.HORIZONTAL) {//水平方向,随机宽度
            layoutParams.width = getRandom(position);
        }
        viewHolder.mTv_name.setLayoutParams(layoutParams);
    }

    //指定RecyclerView有多少个Item
    @Override
    public int getItemCount() {
        return mData.size();
    }

    //创建ViewHolder
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView mTv_name;

        ViewHolder(@NonNull View itemView) {
            super(itemView);
            mTv_name = itemView.findViewById(R.id.tv_name);
            mTv_name.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext, mTv_name.getText().toString(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    //设置线性方向
    public void setLinear(@RecyclerView.Orientation int linear) {
        this.mLinear = linear;
    }

    //获取高度或者宽度,分别返回300,400,200
    private int getRandom(int position) {
        if (position % 3 == 0) {//第一排
            return 300;
        } else if (position % 3 == 1) {//第二排
            return 400;
        } else {
            return 200;
        }
    }
}

3.4 LayoutManager 常见API

这里列出了LayoutManager常见的API,平常都比较需要使用到,特别是在设置能否滚动,滚动位置,滚动方向,以及下拉刷新和上拉加载更多都需要用到这些API。

	//能否横向滚动
    canScrollHorizontally();
    //能否纵向滚动
    canScrollVertically();
    //滚动到指定位置
    scrollToPosition(int position);

	//设置滚动的方向
    setOrientation(int orientation);
    //获取滚动方向
    getOrientation();

	//获取指定位置的Item View
    findViewByPosition(int position);
    //获取第一个完全可见的Item位置
    findFirstCompletelyVisibleItemPosition();
    //获取第一个可见Item的位置
    findFirstVisibleItemPosition();
    //获取最后一个完全可见的Item位置
    findLastCompletelyVisibleItemPosition();
    //获取最后一个可见Item的位置
    findLastVisibleItemPosition();

源码地址

点关注,不迷路


好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才

我是suming,感谢各位的支持和认可,您的点赞、评论、收藏【一键三连】就是我创作的最大动力,我们下篇文章见!

如果本篇博客有任何错误,请批评指教,不胜感激 !

要想成为一个优秀的安卓开发者,这里有必须要掌握的知识架构,一步一步朝着自己的梦想前进!Keep Moving!


相关文章:

理解RecyclerView(一)

 ● RecyclerView的基础使用、网格布局、瀑布流布局

理解RecyclerView(二)

 ● RecyclerView的ItemType(不同条目类型)

理解RecyclerView(三)

 ● RecyclerView的ItemDecoration分割线、增删item动画效果、拖拽和侧滑删除功能

理解RecyclerView(四)

 ● RecyclerView的自定义点击事件、万能ViewHolder和Adapter简单封装

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐