在xml写RecyclerView的控件
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy_main_init"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center" />
在activity里面获取这个空间的ID
val mainInitRecy: RecyclerView = findViewById(R.id.recy_main_init) // 获取控件ID
规划布局
RecyclerView 中的列表项由 LayoutManager 类负责排列。RecyclerView 库提供了三种布局管理器,用于处理最常见的布局情况:
-
LinearLayoutManager将各个项排列在一维列表中。 -
GridLayoutManager将所有项排列在二维网格中:- 如果网格垂直排列,
GridLayoutManager会尽量使每行中所有元素的宽度和高度相同,但不同的行可以有不同的高度。 - 如果网格水平排列,
GridLayoutManager会尽量使每列中所有元素的宽度和高度相同,但不同的列可以有不同的宽度。
- 如果网格垂直排列,
-
StaggeredGridLayoutManager与GridLayoutManager类似,但不要求同一行中的列表项具有相同的高度(垂直网格有此要求)或同一列中的列表项具有相同的宽度(水平网格有此要求)。其结果是,同一行或同一列中的列表项可能会错落不齐。
mainInitRecy.layoutManager = GridLayoutManager(this, 5); // 设置显示布局
实现 Adapter 和 ViewHolder
确定布局后,您需要实现 Adapter 和 ViewHolder。这两个类配合使用,共同定义数据的显示方式。ViewHolder 是包含列表中各列表项的布局的 View 的封装容器。Adapter 会根据需要创建 ViewHolder 对象,还会为这些视图设置数据。将视图与其数据相关联的过程称为“绑定”。**
定义 Adapter 时,您需要替换三个关键方法:
onCreateViewHolder():每当RecyclerView需要创建新的ViewHolder时,它都会调用此方法。此方法会创建并初始化ViewHolder及其关联的View,但不会填充视图的内容,因为ViewHolder此时尚未绑定到具体数据。**onBindViewHolder():RecyclerView调用此方法将ViewHolder与数据相关联。此方法会提取适当的数据,并使用该数据填充 ViewHolder 的布局。例如,如果RecyclerView显示的是一个名称列表,该方法可能会在列表中查找适当的名称,并填充 ViewHolder 的TextViewwidget。getItemCount():RecyclerView 调用此方法来获取数据集的大小。例如,在通讯簿应用中,这可能是地址总数。RecyclerView 使用此方法来确定什么时候没有更多的列表项可以显示。
class SomeRecyAdapter(val someData: List<RecyConstantsBean>) :
RecyclerView.Adapter<SomeRecyAdapter.SomeViewHolder>() {
//适配器传入一个集合 集合的类型是 RecyConstantsBean
var itemClickListener: ListItemClickListener? = null
class SomeViewHolder(view: View) : RecyclerView.ViewHolder(view) {
//获取子条目的布局控件ID
val mImgRecyItem: ImageView
val mTxtRecyItem: TextView
init {
mImgRecyItem = view.findViewById(R.id.img_recy_item)
mTxtRecyItem = view.findViewById(R.id.txt_recy_item)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SomeViewHolder
//设置RecyclerView 子条目的布局
val someView = LayoutInflater.from(parent.context).inflate(R.layout.item_main_recy, null)
return SomeViewHolder(someView)
}
override fun onBindViewHolder(holder: SomeViewHolder, position: Int) {
//这里给子条目控件设置图片跟文字
holder.mImgRecyItem.setImageResource(someData[position].titlePic)
holder.mTxtRecyItem.text = someData[position].title
holder.mImgRecyItem.setOnClickListener {
//当点击子条目图片的时候出发接口回调
itemClickListener?.invoke(position)
}
}
override fun getItemCount(): Int {
//这里控制条目要显示多少
return someData.size
}
}
typealias ListItemClickListener = (Int) -> Unit //设置item控件的点击事件
每个视图项的布局照例在 XML 布局文件中定义。在本例中,应用包含一个 item_main_recy.xml 文件,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="120dp"
android:layout_height="140dp"
android:orientation="vertical"
android:gravity="center"
>
<ImageView
android:id="@+id/img_recy_item"
android:layout_width="90dp"
android:layout_height="90dp"
android:src="@mipmap/ic_launcher"
/>
<TextView
android:id="@+id/txt_recy_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="体验课程"
android:textSize="24sp"
android:textColor="@color/some_recy_item"
/>
</LinearLayout>
设置适配器 传入数据 然后item点击接口回调
val someRecyAdapter = SomeRecyAdapter(mainInitList)//获取适配器 适配器传入数据
mainInitRecy.adapter = someRecyAdapter//设置RecyclerView的适配器
someRecyAdapter.itemClickListener = {
//列表点击的接口回调
Logger.e(it.toString())
}