Kotlin_RecyclerView_实现ListView效果

  • Post author:
  • Post category:其他


使用RecyclerView 可以实现ListView(列表), GridView(网格),StaggeredView(瀑布流)的效果,

并且可以自动回收没有使用的条目。

使用RecyclerView的方法,可以总结如下:


目录


1. 布局文件使用RecyclerView:


2. 创建RecyclerView的条目


3. 定义条目的使用的数据:


4. 创建适配器Adapter 3部曲 (关键)


4.1 继承  RecyclerView.Adapter 并且实现 泛型 RecyclerView.ViewHolder


4.2 构造函数参数传入数据,并使用成员变量保存


4.3 重写获取条目数目、创建ViewHolder、绑定ViewHolder的方法


5.  Activity 3

部曲


5.1 初始化数据


5.2 设置布局管理器


5.3 设置适配器

1. 布局文件使用RecyclerView: activity_main.xml

<?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="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

其中需要在app 的build.gradle中添加RecyclerView包的依赖(不同SDK版本, 会有些许差异):

dependencies {
    //此处省略其它的配置
    implementation 'androidx.recyclerview:recyclerview:1.1.0'

}

2. 创建RecyclerView的条目 : item_list_view

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="90dp">

    <androidx.cardview.widget.CardView
        app:cardUseCompatPadding="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
            <ImageView
                android:id="@+id/user_image"
                android:layout_width="60dp"
                android:layout_height="70dp"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="10dp"
                android:scaleType="fitCenter"
                android:src="@drawable/pic1" />

            <TextView
                android:id="@+id/user_name"
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:layout_marginTop="20dp"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/user_image"
                android:text="User Name1" />

        </RelativeLayout>

    </androidx.cardview.widget.CardView>

</RelativeLayout>

其中CardView 只是起到添加边框的作用,使得看起来稍微好看的,装饰作用,

需要在app 的build.gradle中添加依赖

    //此处省略其它
   implementation 'androidx.cardview:cardview:1.0.0'

3. 定义条目的使用的数据:

UserData,  一个String 类型的名字, 一个对应的图片(Int 类型的id)

package com.example.androidrecyclerviewtest.data

class UserData {
    var userName: String
    var userImageId: Int

    constructor(userNameId: String, userImageId: Int) {
        this.userName = userNameId
        this.userImageId = userImageId
    }
}

其中,名字和图片的资源定义在一个常量类中,方便管理:

pic1~pic12 为图片,可以随意加到drawable资源文件+下,

user_name1 ~user_name12 为名字,可以随意加到strings.xml 中

object CommonConstants {
    val PIC_IDS = mutableListOf(
        R.drawable.pic1,
        R.drawable.pic2,
        R.drawable.pic3,
        R.drawable.pic4,
        R.drawable.pic5,
        R.drawable.pic6,
        R.drawable.pic7,
        R.drawable.pic8,
        R.drawable.pic9,
        R.drawable.pic10,
        R.drawable.pic11,
        R.drawable.pic12
    )

    val USER_NAMES = mutableListOf(
        R.string.user_name1,
        R.string.user_name2,
        R.string.user_name3,
        R.string.user_name4,
        R.string.user_name5,
        R.string.user_name6,
        R.string.user_name7,
        R.string.user_name8,
        R.string.user_name9,
        R.string.user_name10,
        R.string.user_name11,
        R.string.user_name12
    )
}

4. 创建适配器Adapter (关键)

适配器决定了如何把数据映射到条目上显示。

4.1 继承  RecyclerView.Adapter 并且实现 泛型 RecyclerView.ViewHolder

ViewHolder 可以理解为每个条目的显示缓存,是Adpater的关键

class ListViewAdpater :
    RecyclerView.Adapter<ListViewAdpater.InnerViewHolder> {

    class InnerViewHolder : RecyclerView.ViewHolder {
        //此处暂未实现
    }
}

4.2 构造函数参数传入数据,并使用成员变量保存

    private var datas: MutableList<UserData>

    // 1. 适配器持有数据的引用
    constructor(datas: MutableList<UserData>) {
        this.datas = datas
    }

4.3 重写获取条目数目、创建ViewHolder、绑定ViewHolder的方法

    override fun getItemCount(): Int {
        return if (datas != null) {
            datas.size
        } else {
            0
        }
    }
    //2. 创建条目 - 每个条目只会创建一次,后续刷新到仅调用 onBinderViewHolder 进行数据绑定
    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): InnerViewHolder {

        val view = View.inflate(parent.context,R.layout.item_list_view, null)
        return InnerViewHolder(view)
    }
    //3. 绑定数据 -  position 对应数据的下标号 - 数据可以变化,只要数据数目不增加,条目也不会增加
    override fun onBindViewHolder(holder: InnerViewHolder, position: Int) {
        holder.setData(datas[position])
    }

如果要设置

点击Item时响应

,最好是在这里添加监听器(自定义个接口用于回调)。 如果是在

ViewHolder中添加监听

,那么回调中用到的数据可能是

创建ViewHolder时的数据,

并不是

当前绑定的数据

此时,需要实现InnerViewHolder的内部操作,即把数据设置到条目上 (ItemView 为传入的条目)

    class InnerViewHolder : RecyclerView.ViewHolder {
        private var image: ImageView
        private var nameText: TextView

        constructor(itemView: View) : super(itemView) {
            this.nameText = itemView.user_name
            this.image = itemView.user_image
        }

        fun setData(userData: UserData) {
            nameText.text = userData.userName
            image.setImageResource(userData.userImageId)
        }
    }

5.  Activity 3部曲

在Activity 加载包含有recyclerview控件的布局文件

setContentView(R.layout.activity_main)

5.1 初始化数据

    private var datas = mutableListOf<UserData>()

    private fun initDatas() {
        for (index in 0 until USER_NAMES.size) {
            datas.add(
                index,
                UserData(
                    context.getString(USER_NAMES[index]), PIC_IDS[index]
                )
            )
        }
    }

5.2 设置布局管理器

        //2. 创建并设置布局管理器
        var layoutManager = LinearLayoutManager(context)
        layoutManager.orientation = LinearLayoutManager.VERTICAL
        recycler_view.layoutManager = layoutManager

5.3 设置适配器

         //3. 创建并设置adapter
        adapter=
            ListViewAdpater(datas)
        recycler_view.adapter = adapter

虽然很简单,但是在实际操作一遍后,可以加深理解。

这些只是基本操作, 后续会再更新显示不同类型的条目,下拉和上拉刷新等



版权声明:本文为whjk20原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。