Android UI 组件系列(八):ListView 基础用法与适配器详解

发布于:2025-07-26 ⋅ 阅读:(12) ⋅ 点赞:(0)

博客专栏:Android初级入门UI组件与布局

源码:通过网盘分享的文件:Android入门布局及UI相关案例

链接: https://pan.baidu.com/s/1EOuDUKJndMISolieFSvXXg?pwd=4k9n 提取码: 4k9n

一、引言

在上一篇文章《Android UI 组件系列(七):容器 NestedScrollView 的使用场景与协同滚动实战》中,我们讲解了 NestedScrollView 的滚动机制和嵌套使用方式。今天我们来继续深入容器组件系列,聊聊 Android 中最常见的列表组件之一——ListView。

尽管 RecyclerView 已成为更现代的列表解决方案,但 ListView 依然在不少老项目中被广泛使用,对于初学者理解 Android 的适配器机制和 UI 构建也非常重要。

二、ListView 的 UI 结构

在 Android 中,ListView 是一种用于显示垂直滚动列表的容器组件。它通过“适配器”将一组数据源映射到每一个列表项(Item)上,从而实现动态列表的展示。

ListView的XML布局

我们先来看一段最基础的 ListView 使用 XML 布局:

<!-- res/layout/activity_main.xml -->
<ListView
    android:id="@+id/list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@android:color/darker_gray"
    android:dividerHeight="1dp"/>

这段代码定义了一个占满整个屏幕的列表视图,并通过 divider 设置了分隔线颜色与高度。我们只需要给这个 ListView 设置一个适配器,它就可以根据数据动态生成对应数量的列表项。

ListView 的渲染逻辑

在运行时,ListView 会根据你设置的适配器(Adapter)来决定如何渲染每一项数据。整个流程大致如下:

数据源(List / 数组等)

     ↓

适配器(Adapter)

     ↓

生成每个 item 对应的 View(例如 TextView / 自定义布局)

     ↓

交由 ListView 管理显示、滚动、复用

常用的内置 item 布局

在使用 ArrayAdapter 等简单适配器时,Android 提供了一些默认的列表项布局:

  • android.R.layout.simple_list_item_1:只显示一行文本
  • android.R.layout.simple_list_item_2:显示主副两行文本
  • android.R.layout.simple_list_item_checked:带 CheckBox 的样式
  • android.R.layout.simple_list_item_single_choice:单选项样式
  • android.R.layout.simple_list_item_multiple_choice:多选项样式

通过不同的布局选择,你可以快速完成不同风格的列表 UI 原型。

示例:简单展示一个字符串列表

/// 配置ListView
    private fun setupListView() {
        val listView = findViewById<ListView>(R.id.list_view)
        val data = listOf("北京", "上海", "广州", "深圳")
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, data)
        listView.adapter = adapter
        
    }

运行效果如下,每一行都是一个字符串。

三、ArrayAdapter、SimpleAdapter 快速上手

在 ListView 中展示数据的关键,就是选择合适的适配器(Adapter)。对于简单的字符串列表或图文混排效果,Android 提供了两个非常常用的适配器类:

  1. ArrayAdapter:用于展示一维字符串或对象列表;
  2. SimpleAdapter:用于展示键值对数据结构,支持图文混排。

使用 ArrayAdapter 展示文本列表

当你有一个字符串数组,或者只是想展示某个字段列表时,ArrayAdapter 是最简单的选择。

val data = listOf("苹果", "香蕉", "橘子")
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, data)
listView.adapter = adapter

simple_list_item_1 是系统提供的单行文本布局。你也可以替换成自己的布局资源。

这个效果在上面我们已经看过了。

使用 SimpleAdapter 实现图文混排

如果你希望每一行除了文字,还能显示图片,可以使用 SimpleAdapter。它支持将键值对映射到指定的控件上:

    /// 配置图文ListView
    private fun setupImageTextListView() {
        val listView = findViewById<ListView>(R.id.list_view)
        val data = listOf(
            mapOf("title" to "微信", "icon" to R.drawable.ic_wechat),
            mapOf("title" to "QQ", "icon" to R.drawable.ic_qq)
        )

        val adapter = SimpleAdapter(
            this,
            data,
            R.layout.list_item, // 自定义布局
            arrayOf("title", "icon"), // 数据中的 key
            intArrayOf(R.id.text_view, R.id.image_view) // 映射到布局中的控件
        )
        listView.adapter = adapter
    }

示例中,list_item.xml 是我们自定义的布局文件,代码如下:

<!-- res/layout/list_item.xml -->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp">

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginEnd="10dp"/>

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"/>
</LinearLayout>

效果如下:

四、设置点击事件、选中状态

ListView 除了展示内容,更常见的场景是需要响应用户的点击,比如跳转页面、更新 UI 或选中状态。

设置点击事件

我们可以通过 setOnItemClickListener 来监听列表项的点击事件:

listView.setOnItemClickListener { parent, view, position, id ->
    val selectedItem = parent.getItemAtPosition(position)
    Toast.makeText(this, "点击了:$selectedItem", Toast.LENGTH_SHORT).show()
}

常用参数说明:

  • position:当前点击的列表索引;
  • parent.getItemAtPosition(position):获取对应位置的数据项;
  • view:当前 item 对应的视图(可以进一步修改 UI);

设置选中状态(高亮)

如果你想让点击后的列表项有高亮效果,有两种常见方式:

方式一:使用系统自带的 listSelector

在 XML 中设置 ListView 的选择器属性:

<ListView
    android:id="@+id/list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:choiceMode="singleChoice"
    android:listSelector="@android:color/holo_blue_light"/>

方式二:自定义点击后改变 item 背景(适合自定义布局)

如果你使用自定义 item 布局,则可以在点击事件中手动修改背景:

listView.setOnItemClickListener { parent, view, position, id ->
    for (i in 0 until parent.childCount) {
        parent.getChildAt(i).setBackgroundColor(Color.WHITE)
    }
    view.setBackgroundColor(Color.LTGRAY)
}

注意:这种方式只适用于屏幕内可见的 item,不会持久记住“选中状态”,适合轻量使用。

通常我们需要配合修改数据状态,根据数据来设置选中状态或者其它状态。

五、简单列表展示 + 图文混排

前面我们已经了解了 ArrayAdapter 和 SimpleAdapter 的基础用法,也会给 ListView 设置点击事件。那么接下来我们就用一套完整的代码,实现一个带图标和文字的图文混排列表效果。

数据源定义

我们使用 List<Map<String, Any>> 的数据结构,每个 item 包含 title 和 icon 两个字段:

val data = listOf(
    mapOf("title" to "微信", "icon" to R.drawable.ic_wechat),
    mapOf("title" to "QQ", "icon" to R.drawable.ic_qq),
    mapOf("title" to "钉钉", "icon" to R.drawable.ic_dingding)
)

自定义布局 list_item.xml

放在 res/layout/list_item.xml 中,展示左图右文的横向结构:

<!-- res/layout/list_item.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    android:padding="10dp">

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginEnd="16dp"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:textColor="#333333" />
</LinearLayout>

绑定适配器

使用 SimpleAdapter 将数据与布局绑定:

val adapter = SimpleAdapter(
    this,
    data,
    R.layout.list_item,
    arrayOf("title", "icon"),
    intArrayOf(R.id.text_view, R.id.image_view)
)

adapter.setViewBinder { view, data, _ ->
    if (view is ImageView && data is Int) {
        view.setImageResource(data)
        true
    } else {
        false
    }
}

listView.adapter = adapter
⚠️ SimpleAdapter 默认不会处理图片资源,需要设置 setViewBinder 手动绑定图片。

设置点击事件

listView.setOnItemClickListener { _, _, position, _ ->
            val item = data[position]
            // 处理点击事件
            val title = item["title"] ?: "未知"
            Toast.makeText(this, "点击了: $title", Toast.LENGTH_SHORT).show()
        }

运行效果如下:

六、结语

本篇我们聚焦于 ListView 的基础使用方式,围绕其 UI 结构与适配器机制展开,主要介绍了以下内容:

✅ ListView 的布局结构与渲染逻辑;

✅ ArrayAdapter 适用于快速展示字符串列表;

✅ SimpleAdapter 可轻松实现图文混排展示;

✅ 如何监听点击事件与设置选中高亮;

✅ 结合完整示例,快速构建图文列表 UI;

虽然 ListView 的使用已经较为成熟,但它依然是理解 Android 列表机制、适配器模式、性能优化的良好入门途径。在项目初期阶段或快速原型开发中,ListView 仍具备一定实用价值。


网站公告

今日签到

点亮在社区的每一天
去签到