Android之RecyclerView显示数据列表和网格

一、RecyclerView的优势

RecyclerView 的最大优势在于,它对大型列表来说非常高效:

  • 默认情况下,RecyclerView 仅会处理或绘制当前显示在屏幕上的项。例如,如果您的列表包含一千个元素,但只有 10 个元素可见,那么 RecyclerView 仅会完成在屏幕上绘制这 10 个项的工作。当用户滚动时,RecyclerView 会确定应在屏幕上显示哪些新项,然后仅完成显示这些项的工作。
  • 当某个项滚动出屏幕时,RecyclerView 会回收其视图。也就是说,这个项中会填充滚动到屏幕上的新内容。RecyclerView 的这种行为可以节省大量处理时间,并能让列表顺畅地滚动。
  • 当某个项发生变化时,RecyclerView 无需重新绘制整个列表即可更新该项。在显示包含复杂项的长列表时,这可以极大地提高效率!

二、RecyclerView中显示数据的步骤

如需在 RecyclerView 中显示您的数据,您需要以下几个部分:

  • 要显示的数据。即列表项中要显示的内容。
  • 在布局文件中定义的一个 RecyclerView 实例,用作视图的容器。RecyclerView包含与您的数据对应的视图的 ViewGroup,它本身是一个视图,因此,将 RecyclerView 添加到布局中的方式与添加任何其他界面元素相同。
  • 一个数据项的布局。如果所有列表项看起来都一样,您可以对所有这些列表项使用相同的布局,但这不是强制性要求。项布局必须与 fragment 的布局分开创建,以便一次创建一个项视图,并在其中填充数据。
  • 一个布局管理器。布局管理器负责排列列表中的各个元素。您可以使用 RecyclerView 库提供的某个布局管理器,也可以定义自己的布局管理器。布局管理器均基于库的 LayoutManager 抽象类。
  • 一个 ViewHolder。该 ViewHolder 用于扩展 ViewHolder 类。它包含视图信息,用于显示项布局中的一项。ViewHolder 还会添加一些信息,供 RecyclerView 用于在屏幕上高效移动视图。可以通过扩展 RecyclerView.ViewHolder 来定义 ViewHolder。
  • 一个适配器。该适配器可将您的数据与 RecyclerView 相关联。它会调整数据,使其可在 ViewHolder 中显示。RecyclerView 会使用适配器确定如何在屏幕上显示数据。可以通过扩展 RecyclerView.Adapter 来定义 Adapter。

三、实现RecyclerView

1. 添加依赖项

在模块的 build.gradle 中添加 RecyclerView 的依赖项:

复制代码
implementation("androidx.recyclerview:recyclerview:1.3.2")

2. 准备要显示的数据

本例只是演示 RecyclerView 的用法,故只简单显示颜色列表,数据项中只需定义一个 TextView 来显示颜色即可。实际项目中需根据需求定义相应的数据类来保存列表项内容。

复制代码
val listData = arrayOf("yellow", "red", "blue")

3. 在 xml 中添加RecyclerView组件

布局 recyclerview_main.xml

cpp 复制代码
<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

4. 创建 列表项布局

本例中 RecyclerView 显示了一个简单的文本元素列表,每个视图项的布局在xml中定义,recyclerview_item.xml 布局如下:

cpp 复制代码
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dp">
    
    <TextView
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/element_text"
        android:gravity="center_vertical"/>

</FrameLayout>

5. 选择布局管理器

RecyclerView 中的列表项由 LayoutManager 类负责排列。RecyclerView 库提供了三种布局管理器,用于处理最常见的布局情况:

  • LinearLayoutManager 将各个项排列在一维列表中。
  • GridLayoutManager 将项排列在二维网格中:
    • 如果网格垂直排列,GridLayoutManager 会尽量使每行中所有元素的宽度和高度相同,但不同的行可以有不同的高度。
      • 如果网格水平排列,GridLayoutManager 会尽量使每列中所有元素的宽度和高度相同,但不同的列可以有不同的宽度。
  • StaggeredGridLayoutManager 与 GridLayoutManager 类似,但不要求同一行中的表项具有相同的高度(垂直网格有此要求)或同一列中的列表项具有相同的宽度(水平网格有此要求)。其结果是,同一行或同一列中的列表项可能会错落不齐。

6. 实现ViewHolder和适配器Adapter

ViewHolder 是包含列表中各列表项的布局的 View 的封装容器。Adapter 会根据需要创建 ViewHolder 对象,还会为这些视图设置数据。将视图与其数据相关联的过程称为"绑定"。这两个类配合使用,共同定义数据的显示方式。

定义适配器时,您需要替换三个关键方法:

  • onCreateViewHolder():每当 RecyclerView 需要创建新的 ViewHolder 时,它都会调用此方法。此方法会创建并初始化 ViewHolder 及其关联的 View,但不会填充视图的内容,因为 ViewHolder 此时尚未绑定到具体数据。
  • onBindViewHolder():RecyclerView 调用此方法将 ViewHolder 与数据相关联。此方法会提取适当的数据,并使用该数据填充 ViewHolder 的布局。例如,如果 RecyclerView 显示的是一个名称列表,该方法可能会在列表中查找适当的名称,并填充 ViewHolder 的 TextView widget。
  • getItemCount():RecyclerView 调用此方法来获取数据集的大小。例如,在通讯簿应用中,这可能是地址总数。RecyclerView 使用此方法来确定什么时候没有更多的列表项可以显示。

下面是一个典型的简单 Adapter 示例,该 Adapter 包含一个显示数据列表的嵌套 ViewHolder。在本例中,RecyclerView 显示了一个简单的文本元素列表。系统会向 Adapter 传递一个字符串数组,该数组包含了 ViewHolder 元素的文本。

cpp 复制代码
	package com.android.jetpack.recyclerview
	
	import android.view.LayoutInflater
	import android.view.View
	import android.view.ViewGroup
	import android.widget.TextView
	import androidx.recyclerview.widget.RecyclerView
	import com.android.jetpack.R
	
	class CustomAdapter(private val dataSet: Array<String>)
	    : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
	
	    // 列表项视图容器
	    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
	        // 列表项内控件
	        val textview: TextView
	        init {
	            textview = view.findViewById(R.id.tv_text)
	        }
	    }
	
	    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
	        val view = LayoutInflater.from(parent.context)
	            .inflate(R.layout.recyclerview_item, parent, false)
	        return ViewHolder(view)
	    }
	
	    override fun getItemCount(): Int {
	        return dataSet.size
	    }
	
	    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
	        holder.textview.text = dataSet[position]
	    }
	}

7. 使用RecyclerView

在 RecyclerViewActivity 中使用 RecyclerView 的代码:

cpp 复制代码
	package com.android.jetpack.recyclerview
	
	import android.os.Bundle
	import android.os.PersistableBundle
	import androidx.activity.ComponentActivity
	import androidx.recyclerview.widget.LinearLayoutManager
	import com.android.jetpack.databinding.RecyclerviewMainBinding
	
	class RecyclerViewActivity : ComponentActivity() {
	
	    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
	        super.onCreate(savedInstanceState, persistentState)
	
	        val binding = RecyclerviewMainBinding.inflate(layoutInflater)
	        setContentView(binding.root)
	
	        val listData = arrayOf("yellow", "red", "blue")
	        val adapter = CustomAdapter(listData)
	        binding.recyclerview.adapter = adapter
	        binding.recyclerview.layoutManager = LinearLayoutManager(this)
	    }
	}

参考文档:

https://developer.android.google.cn/codelabs/kotlin-android-training-recyclerview-fundamentals

https://developer.android.google.cn/develop/ui/views/layout/recyclerview?hl=zh_cn

相关推荐
Y40900114 分钟前
数据库基础知识——聚合函数、分组查询
android·数据库
没有了遇见5 小时前
Android 原生定位(替代高德 / 百度等三方定位)<终极版本>
android
2501_916008896 小时前
iOS 抓包工具有哪些?全面盘点主流工具与功能对比分析
android·ios·小程序·https·uni-app·iphone·webview
2501_915921436 小时前
iOS混淆工具实战 视频流媒体类 App 的版权与播放安全保护
android·ios·小程序·https·uni-app·iphone·webview
CYRUS_STUDIO6 小时前
LLVM 全面解析:NDK 为什么离不开它?如何亲手编译调试 clang
android·编译器·llvm
CYRUS_STUDIO6 小时前
静态分析神器 + 动态调试利器:IDA Pro × Frida 混合调试实战
android·逆向
g_i_a_o_giao9 小时前
Android8 binder源码学习分析笔记(一)
android·java·笔记·学习·binder·安卓源码分析
翻滚丷大头鱼9 小时前
android 四大组件—BroadcastReceiver
android
人生游戏牛马NPC1号9 小时前
学习 Android (二十) 学习 OpenCV (五)
android·opencv·学习
2501_9160088910 小时前
uni-app iOS 日志与崩溃分析全流程 多工具协作的实战指南
android·ios·小程序·https·uni-app·iphone·webview