首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >[Android 从零到一] RecyclerView 入门

[Android 从零到一] RecyclerView 入门

原创
作者头像
hunter android
发布2026-06-17 15:52:46
发布2026-06-17 15:52:46
590
举报

RecyclerView 能取代 ListView

在 Android 开发的早期版本中,ListView 是列表展示的标配。但随着 App 交互越来越复杂,ListView 的局限性逐渐暴露:

  • 性能瓶颈:没有强制实现 ViewHolder 模式,开发者容易写出低效代码
  • 扩展性差:水平滚动、网格布局、瀑布流都需要额外封装
  • 动画缺失:增删列表项需要手动写动画,繁琐且容易出错

Google 在 Android 5.0 推出了 RecyclerView,它设计了一套灵活的架构,把布局、动画、回收机制全都解耦,让列表开发变得既高效又可控。如今 RecyclerView 已经成为 Android 列表开发的不二之选。

核心架构:三驾马车

RecyclerView 之所以灵活,是因为它将职责拆分给了三个关键组件:

组件

职责

类比

Adapter

将数据绑定到 ViewHolder,决定每个位置显示什么

生产线上的工人

LayoutManager

控制列表项如何排列(线性/网格/瀑布流)

货架管理员

ItemAnimator

管理增删移改时的动画效果

魔术师

这三者各司其职,想改布局方式?换一个 LayoutManager 就行。想改动画效果?换一个 ItemAnimator 就行。这就是"组合优于继承"的典范。

基础用法:三步走

第一步:添加依赖

代码语言:javascript
复制
// app/build.gradle.kts
dependencies {
    implementation("androidx.recyclerview:recyclerview:1.3.2")
}

第二步:创建 ViewHolder 与 Adapter

ViewHolder 是 RecyclerView 的灵魂。它缓存了列表项中所有 View 的引用,避免反复调用 findViewById:

代码语言:javascript
复制
class Article(val title: String, val summary: String, val time: String)

class ArticleAdapter(
    private val articles: MutableList<Article>
) : RecyclerView.Adapter<ArticleAdapter.ViewHolder>() {

    // 1. 自定义 ViewHolder 持有 item 中的视图引用
    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tvTitle: TextView = itemView.findViewById(R.id.tv_title)
        val tvSummary: TextView = itemView.findViewById(R.id.tv_summary)
        val tvTime: TextView = itemView.findViewById(R.id.tv_time)
    }

    // 2. 创建 ViewHolder —— 加载 item 布局
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_article, parent, false)
        return ViewHolder(view)
    }

    // 3. 绑定数据 —— 把数据填到 ViewHolder 的视图中
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val article = articles[position]
        holder.tvTitle.text = article.title
        holder.tvSummary.text = article.summary
        holder.tvTime.text = article.time
    }

    // 4. 告诉 RecyclerView 一共有多少条数据
    override fun getItemCount(): Int = articles.size
}

第三步:在 Activity / Fragment 中使用

代码语言:javascript
复制
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var adapter: ArticleAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 1. 准备数据
        val data = mutableListOf(
            Article("Android 14 新特性抢先看",
                    "一起来看看 Android 14 带来了哪些亮眼的新功能",
                    "2026-06-10"),
            Article("Kotlin 1.9 协程改进",
                    "Kotlin 1.9 对协程做了大量性能优化",
                    "2026-06-08"),
            Article("Jetpack Compose 实战",
                    "用 Compose 实现一个完整的天气 App",
                    "2026-06-05")
        )

        // 2. 设置 LayoutManager —— 这里是垂直线性布局
        binding.recyclerView.layoutManager = LinearLayoutManager(this)

        // 3. 创建并设置 Adapter
        adapter = ArticleAdapter(data)
        binding.recyclerView.adapter = adapter
    }
}

对应的 item 布局文件 res/layout/item_article.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_summary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:textSize="14sp"
        android:textColor="#666666" />

    <TextView
        android:id="@+id/tv_time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:textSize="12sp"
        android:textColor="#999999" />

</LinearLayout>

LayoutManager 三种布局方式

RecyclerView 内置了三种布局管理器,满足绝大部分场景:

1. LinearLayoutManager — 线性排列

代码语言:javascript
复制
// 垂直列表(默认)
LinearLayoutManager(context)
// 水平列表
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)

2. GridLayoutManager — 网格排列

代码语言:javascript
复制
// 3 列的网格
GridLayoutManager(context, 3)

3. StaggeredGridLayoutManager — 瀑布流

代码语言:javascript
复制
// 2 列瀑布流(每项高度可以不同)
StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)

点击事件的优雅处理

RecyclerView 没有提供 setOnItemClickListener,但我们可以利用 ViewHolder 自身来处理点击:

代码语言:javascript
复制
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val tvTitle: TextView = itemView.findViewById(R.id.tv_title)
    val tvSummary: TextView = itemView.findViewById(R.id.tv_summary)

    init {
        // 整项点击
        itemView.setOnClickListener {
            val pos = adapterPosition
            if (pos != RecyclerView.NO_POSITION) {
                onItemClick?.invoke(pos)
            }
        }
    }
}

// 在 Adapter 中定义回调
var onItemClick: ((Int) -> Unit)? = null

// 在 Activity 中设置
adapter.onItemClick = { position ->
    Toast.makeText(this, "点击了第 $position 项", Toast.LENGTH_SHORT).show()
}

避坑指南

  1. 一定要用 ViewHolder 模式:RecyclerView 强制使用 ViewHolder,不要试图绕过它。
  2. notifyDataSetChanged 性能差:增删单项时用 notifyItemInserted/Removed 代替整体刷新。
  3. setHasFixedSize true:如果列表高度是固定的,设置这个标志可以避免不必要的布局计算。
  4. 不要嵌套滑动:RecyclerView 嵌套 RecyclerView 会导致滑动冲突,慎用 NestedScrollView 包裹 RecyclerView。
  5. DiffUtil:数据量大时使用 DiffUtil 进行差异更新,避免整个列表闪烁。

总结

RecyclerView 是 Android 列表中最重要的组件之一。掌握它的核心三要素—Adapter、LayoutManager、ViewHolder—就能应对 90% 的列表场景。在此基础上,再学习 DiffUtil、ItemDecoration、自定义 LayoutManager 等进阶内容,就能写出高性能的列表页面。

下一篇文章我们将深入 RecyclerView 的进阶使用,包括 DiffUtil 高效更新、ItemDecoration 装饰、以及自定义 LayoutManager。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RecyclerView 能取代 ListView
    • 核心架构:三驾马车
    • 基础用法:三步走
      • 第一步:添加依赖
      • 第二步:创建 ViewHolder 与 Adapter
      • 第三步:在 Activity / Fragment 中使用
    • LayoutManager 三种布局方式
      • 1. LinearLayoutManager — 线性排列
      • 2. GridLayoutManager — 网格排列
      • 3. StaggeredGridLayoutManager — 瀑布流
    • 点击事件的优雅处理
    • 避坑指南
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档