Android - 强大的RecyclerView
Posted 小柴的回忆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android - 强大的RecyclerView相关的知识,希望对你有一定的参考价值。
强大的RecyclerView
RecyclerView是androidx库的控件,低版本可能需要自行导入,但现在的版本是默认加上的
RecyclerView是一个强大的控件,主要用于替代ListView,ListView能实现的功能,他也能实现,他比ListView更好用,更方面,功能更加全面。
一、RecyclerView的使用主要涉及3个类:RecyclerView、Adapter,和ViewHolder
1.RecyclerView类
RecyclerView是ViewGroup的子类,每一个列表项都是作为一个View子对象显示的。这些
View子对象可简单可复杂,这取决于列表项要显示些什么。
RecyclerView顾名思义回收视图,他的一大特点就是回收,他只会显示屏幕能显示的几个布局,当滑动的时候,会将不要的视图回收,然后显示新的视图。而RecyclerView的任务仅仅只是回收和定位屏幕上的View,其余的功能都是交给Adapter和ViewHolder处理
2.ViewHolder
而ViewHolder所做的任务更少,就只有一个,就是用于容纳View视图,因为RecyclerView不会创建视图,所以视图都是ViewHolder创建的
3.Adapter
而上面的ViewHolder是由Adapter创建的,同时他是一个控制器,控制着RecyclerView。先创建好ViewHolder,绑定ViewHolder至模型层,然后从模型层取出数据,提供给RecyclerView显示
二、RecyclerView的使用
简单的吹完RecyclerView的理论,那就开始使用吧
这里我将RecyclerView用于显示学生数据
1.创建一个Student类
里面有4个数据,头像图片,名字,成绩与自我介绍
class Student(val name : String, val grade : Int, val headerImg : Int, val sign : String)
2.创建一个item的视图
也就是列表中一项的视图
这里采用的是ConstraintLayout约束布局,不懂的小伙伴点这里 ↓
约束布局ConstraintLayout看这一篇就够了
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/header"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:layout_constraintRight_toLeftOf="@id/barrier"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/header"/>
<TextView
android:id="@+id/sign"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:textSize="12sp"
app:layout_constraintLeft_toRightOf="@id/header"
app:layout_constraintRight_toLeftOf="@id/barrier"
app:layout_constraintTop_toBottomOf="@id/name"/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
app:barrierDirection="end"
app:constraint_referenced_ids="name, sign"/>
<TextView
android:id="@+id/grade"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
app:layout_constraintLeft_toRightOf="@id/barrier"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
3.随便找几张图片作为头像
4.创建一个StudentAdapter适配器与ViewHolder
//创建一个StudentAdapter,构造函数传入一个Student列表数据,
// 同时继承RecyclerView.Adapter<>类,传入的泛型类是继承ViewHolder的类,所以下面的ViewHolder符合
class StudentAdapter(private val context : Context, private val studentList: List<Student>) : RecyclerView.Adapter<StudentAdapter.ViewHolder>()
//该类是继承RecyclerView的内部类ViewHolder
//这里传入的view,通常都是一个item的最外部类,也就是上面创建的xml文件,用于获取该item中的所有控件实例
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
val studentHeader : ImageView = view.findViewById(R.id.header)
val studentName : TextView = view.findViewById(R.id.name)
val studentSign : TextView = view.findViewById(R.id.sign)
val studentGrade : TextView = view.findViewById(R.id.grade)
//看方法名就知道,这是用于创建ViewHolder实例的,同时将实例返回
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder
//创建视图
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_student, parent, false)
return ViewHolder(view)
//用于对item进行数据赋值
override fun onBindViewHolder(holder: ViewHolder, position: Int)
val student = studentList[position]
holder.studentHeader.setImageResource(student.headerImg)
holder.studentName.text = student.name
holder.studentSign.text = student.sign
holder.studentGrade.text = "等级:$student.grade"
holder.studentGrade.setOnClickListener //添加了一个点击成绩的点击事件,用于弹出一个Toast
Toast.makeText(context, "$student.name同学的等级是:$student.grade", Toast.LENGTH_SHORT).show()
//用于告诉RecyclerView一共有多少个item
override fun getItemCount() = studentList.size
5.设置Activity的布局
创建好了RecyclerView要使用的内容, 就要创建一个RecyclerView了
修改activity_main布局,里面就只有一个占满全屏的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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
class MainActivity : AppCompatActivity()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView : RecyclerView = findViewById(R.id.list) //获取recyclerView实例
val layoutManager = LinearLayoutManager(this) //获取线性布局管理实例
recyclerView.layoutManager = layoutManager //设置recyclerView的布局管理为线性布局管理
val studentList : ArrayList<Student> = init() //创建一个学生列表
val adapter = StudentAdapter(this, studentList) //创建一个StudentAdapter
recyclerView.adapter = adapter //设置recyclerView的适配器为StudentAdapter的适配器
//获取一个学生列表
fun init() : ArrayList<Student>
val students = ArrayList<Student>()
var i = 1
repeat(100)
val resource = when //主要用户显示不同的头像,嘿嘿
i % 3 == 0 ->
R.drawable.header1
i % 3 == 1 ->
R.drawable.header2
else ->
R.drawable.header3
students.add(Student("我是刘同学$i号", (1..10).random(), resource, "我就是我,我就是刘同学"))
i += 1
return students
这就大功告成了,一个简单的列表实现了
6.水平方向布局
主要是修改recyclerView.layoutManager = 布局管理
水平方向最简单,只需要修改这里既可
val layoutManager = LinearLayoutManager(this) //获取线性布局管理实例
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
recyclerView.layoutManager = layoutManager //设置recyclerView的布局管理为线性布局管理
修改item_student
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/header"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/grade"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
app:layout_constraintLeft_toRightOf="@id/header"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/sign"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/name"/>
</androidx.constraintlayout.widget.ConstraintLayout>
7.瀑布流布局
val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) //获取瀑布流布局管理实例
recyclerView.layoutManager = layoutManager //设置recyclerView的布局管理为瀑布流布局管理
item_student布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/header"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/grade"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
app:layout_constraintLeft_toRightOf="@id/header"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/sign"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/name"/>
</androidx.constraintlayout.widget.ConstraintLayout>
三、多item布局
我们上面的内容都是单item布局,什么意思呢,就是所有的数据都是使用同一个item的视图
而多item布局是可以使用多个不通的item布局,这里我们就使用左右不同的视图来区分
而我这里就简单举例,所以只用了不同的颜色背景与不同的布局来区分
1.设置左右item布局
首先是item_left_student
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/teal_200"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/header"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/grade"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
app:layout_constraintLeft_toRightOf="@id/header"
Android - 强大的RecyclerView