前言:

  • RecyclerView 是如何经过测量、布局,最终绘制到屏幕上
  • RecycleView 是在 Android 5.0 版本作为 support-v7 的一个组件出现,高效替代了最初的 ListView 等列表 组件。使用上实现了视图代码解耦,功能上具备强大的 item 复用机制,并且提供默认 多种 LayoutMananger 用来处理多种布局。
  • RecyclerView 使用了 ViewHolder 模式,这 样做可以提高性能,因为它无需频繁调用 findViewById()方法即可访问表项的视图。
  • 在新版的Android开发中,RecyclerView控件被内置到Android Studio中,不需要再去引入依赖项,直接配置即可。

RecyclerView的基本使用

RecyclerView组件

  1. 新建一个页面(Activity),在里面引入RecyclerView控件

  1. 新建一个子组件的item页面,来用作每个组件的展示模板,例如下图这样。

RecyclerViewHolder类

  • RecyclerView中的ViewHolder类主要构造方法将子组件(单条数据)的ui和组件对象(Java类)关联起来。

  • 比如上图我的子组件,我要多条展示的这些数据,每条数据的名字(name),图片(iv),描述(introduce)是各不相同的,所以要配置它们,将这些组件用Java类关联起来,然后用Java类方法进行修改和批量展示

  • 相关代码:

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
package com.example.applicationtest.recyclerview;

import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.applicationtest.R;
import androidx.recyclerview.widget.RecyclerView;

public class RecyclerViewHolder extends RecyclerView.ViewHolder {
//展示单条数据的界面组件对象
TextView name;
ImageView iv;
TextView introduce;

//构造方法:将组件(ui)与组件对象(java类)关联起来
public RecyclerViewHolder(View view) {
super(view);
//关联id = name的组件
name = (TextView) view.findViewById(R.id.name);
//关联id = iv的组件
iv = (ImageView) view.findViewById(R.id.iv);
//关联id = introduce的组件
introduce = (TextView) view.findViewById(R.id.introduce);
}
}

RecyclerAdapter类

  • RecyclerView中的Adapter是适配器、数据和视图对接的桥梁。
  • 简单来说,就是新建一个类,在里面设置一些方法,按照item页面的那个模板批量生产子组件,然后将生产的这些子组件塞到一开始新建的那个RecyclerView控件里面,由上往下一个一个排。
  • 相关代码:
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
package com.example.applicationtest.recyclerview;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
import com.example.applicationtest.R;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder>{
// 创建两个数组包含要展示的数据图片、姓名和它们的详细介绍
private String[] names = { "橘猫", "葫芦娃", "小怪兽", "哆啦COS梦", "小猪佩奇", "睡爆emo", "逗乐表情包", "小松鼠", "小鲸鱼", "兔子"};
private int[] icons = {R.drawable.a1,R.drawable.a2,R.drawable.a3,R.drawable.a4,R.drawable.a5,
R.drawable.a6,R.drawable.a7,R.drawable.a8,R.drawable.a9,R.drawable.a10};
private String[] introduces = {
"橘猫,路边看到的小猫,好像隐藏着什么强大的力量,感觉这不是一只普通的小猫。",
"葫芦娃,送头之王,有七兄弟,葫芦娃救爷爷一个一个送",
"小怪兽,凹凸曼的好朋友,喜欢和凹凸曼一起去逗乐,特摄节目中的超级猪脚。",
"COS哆啦A梦的小朋友,简称哆啦COS梦,可爱,萌,就是没有哆啦A梦那么圆那么胖。",
"小猪佩奇,一只可爱的粉色小猪,貌似很受小孩子的欢迎,虽然我不知道这有啥好看就是了,说不定很逗乐。",
"睡爆emo,上数学课英文课的时候大概就是这样了,梦里什么都有。",
"逗乐表情包,一个表情包,挺逗乐的,不过现在估计没什么人用了,时代变了大人。",
"小松鼠,挺可爱挺萌的,长得还挺像皮卡丘,好想抓一只拿回家里养,就是不知道会不会发电。",
"小鲸鱼,能够头上喷水的一种鱼,遭受人类的迫害和捕杀,现在濒临灭绝了。",
"兔子,一种胆小的动物,突然喧闹声、生人和陌生动物,如猫狗等都会使它惊慌失措。"
};

@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// 加载展示单条数据的布局文件recycler_item.xml
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item,parent,false);
RecyclerViewHolder holder = new RecyclerViewHolder(view);
return holder;
}
//展示单条数据,index代表数据在数组中的下标
@Override
public void onBindViewHolder(RecyclerViewHolder holder, int index) {
//设置数组names[index]为展示的id为name的text组件
holder.name.setText(names[index]);
//设置数组icons[index]为展示的id为iv的Image组件
holder.iv.setImageResource(icons[index]);
//设置数组introduces[index]为展示的id为introduce的text组件
holder.introduce.setText(introduces[index]);
}
// 获取所有数据的数量
@Override
public int getItemCount() {
return names.length;
}

​ 上面的代码看上去可能有点长,其实一点都不复杂,一开始的新建的三个数组就是要批量生产的子组件的数据。

​ 在onCreateViewHolder里,先加载子组件item的模板布局,然后将模板布局里面的子组件通过RecyclerHolder类匹配到Java对象上。

​ 在onBindViewHolder里,将三个数组里的数据,set到item的模板布局上面,简单来说就是拿一个模板,向里面按格式写入东西。

​ 最后,再设置一个getItemCount()方法,获取要批量生产的子组件数量。

RecyclerViewActivtiy类

  1. 到需要多条展示数据的页面Activtiy类里面
  2. 新建两个对象,一个是RecyclerView类的对象和适配器RecyclerViewAdapter类的对象
1
2
private RecyclerView mRecyclerView;
private RecyclerViewAdapter mAdapter;
  1. 布局文件通过findViewById()找到一开始新建的那个Recycler控件
  2. 然后直接按下面的代码一样配置即可
  • 相关代码:
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 com.example.applicationtest.recyclerview;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.applicationtest.R;
import android.os.Bundle;

public class RecyclerViewActivity extends AppCompatActivity {

private RecyclerView mRecyclerView;
private RecyclerViewAdapter mAdapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 加载布局文件,里面有recyclerview组件
setContentView(R.layout.activity_recycler_view_activity);
//建立组件对象与组件的关联
mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);
//设置recyclerview中展现多条数据的方式
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//创建适配器对象
mAdapter = new RecyclerViewAdapter();
//recyclerview组件对象设置适配器对象,显示recyclerview组件
mRecyclerView.setAdapter(mAdapter);
}
}

实现效果

Uq5DNY.gif