Kotlin RecyclerView 简单使用

2,479 阅读3分钟

在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 的 TextView widget。
  • 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())
}