Flutter 零基础入门(二十九):ListView 进阶 —— 自定义列表项与复杂布局

Flutter 零基础入门(二十九):ListView 进阶 ------ 自定义列表项与复杂布局

在上一篇中,我们已经学会了:

  • ListView 的基本使用
  • 垂直滚动列表
  • 用 List + map 快速生成列表

但你一定已经意识到一个问题:

❓ 真实 App 里的列表,根本不是一行 Text

这一篇,我们就来解决这个问题。


一、真实 App 的列表长什么样?

你在手机上看到的列表通常是:

  • 一张图片
  • 多行文字
  • 时间 / 状态 / 标签
  • 点击跳转详情页

📌 这意味着:

ListView 的核心不是 ListView,而是"列表项 Widget"


二、ListView 的本质回顾

先记住一句非常重要的话:

ListView = 滚动容器
每一项 = 普通 Widget

所以,只要你会写 Widget,

你就能写任何复杂列表项。


三、最基础的自定义列表项结构

我们先从一个"信息卡片"开始。

示例目标效果(结构)

图片 \] 标题 副标题 时间 --- ### 1️⃣ 数据准备 ```dart List> dataList = [ { 'title': 'Flutter 入门', 'subTitle': '零基础学 Flutter', 'time': '2024-01-01' }, { 'title': 'Dart 语言', 'subTitle': 'Flutter 的基础', 'time': '2024-01-02' }, ]; *** ** * ** *** #### 2️⃣ ListView + map ListView( children: dataList.map((item) { return buildItem(item); }).toList(), ) 📌 关键点来了: 👉 **每一项单独抽成一个 Widget 方法** *** ** * ** *** ### 四、封装列表项 Widget(非常重要) #### 1️⃣ 列表项方法 Widget buildItem(Map item) { return Container( padding: EdgeInsets.all(12), margin: EdgeInsets.symmetric(vertical: 8, horizontal: 12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( color: Colors.black12, blurRadius: 4, ) ], ), child: Row( children: [ // 左侧占位图片 Container( width: 60, height: 60, color: Colors.grey[300], ), SizedBox(width: 12), // 右侧文字区域 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item['title']!, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), SizedBox(height: 4), Text(item['subTitle']!), SizedBox(height: 4), Text( item['time']!, style: TextStyle(color: Colors.grey, fontSize: 12), ), ], ), ), ], ), ); } *** ** * ** *** ### 五、为什么要"封装列表项"? 这是一个**非常重要的工程习惯**: ✅ 代码更清晰 ✅ 方便复用 ✅ 易维护 ✅ 真实项目写法 📌 记住: > **ListView 只负责"列表" > Item Widget 负责"长相"** *** ** * ** *** ### 六、点击列表项(交互的第一步) 真实 App 的列表一定是**可以点的**。 #### 1️⃣ 使用 GestureDetector GestureDetector( onTap: () { print('点击了 ${item['title']}'); }, child: buildItem(item), ); *** ** * ** *** #### 2️⃣ 完整写法示例 ListView( children: dataList.map((item) { return GestureDetector( onTap: () { print('点击了 ${item['title']}'); }, child: buildItem(item), ); }).toList(), ) *** ** * ** *** ### 七、ListView.builder(必须知道) 当数据很多时(比如上百条): 👉 **推荐使用 ListView.builder** #### 示例: ListView.builder( itemCount: dataList.length, itemBuilder: (context, index) { return buildItem(dataList[index]); }, ); 📌 优点: * 性能更好 * 按需加载 * 企业级写法 *** ** * ** *** ### 八、新手最容易犯的 5 个错误 ❌ 列表项写在 build 里一大坨 ❌ ListView 嵌套 Column 不加 Expanded ❌ 不封装 item ❌ 写死高度导致溢出 ❌ 数据和 UI 混在一起 *** ** * ** *** ### 九、本篇你真正掌握了什么? 你已经学会: * ListView 的工程化写法 * 自定义复杂列表项 * Row + Column 组合布局 * 列表项点击交互 * ListView.builder 的正确使用 📌 到这里为止: > **你已经具备开发"信息流页面"的能力** *** ** * ** *** ### 十、一句话总结 > **ListView 不难, > 难的是"把列表项当成普通 Widget 来设计"** *** ** * ** *** ### 🔜 下一篇预告 **《Flutter 零基础入门(三十):GridView 网格布局 ------ 商品页与九宫格必学》** 下一篇我们将学习: * GridView.count * GridView.builder * 九宫格 / 商品列表 * 电商 App 常见布局 🚀 **Flutter UI 能力,将在下一篇彻底补齐**

相关推荐
ZC跨境爬虫16 小时前
跟着MDN学HTML_day_48:(Node接口)
前端·javascript·ui·html·音视频
南 阳17 小时前
Python从入门到精通day66
开发语言·python
PieroPc17 小时前
CAMWATCH — 局域网摄像头监控系统 Fastapi + html
前端·python·html·fastapi·监控
十八旬17 小时前
快速安装ClaudeCode完整指南
开发语言·windows·python·claude
前进的李工18 小时前
EXPLAIN输出格式全解析:JSON、TREE与可视化
开发语言·数据库·mysql·性能优化·explain
Byron Loong18 小时前
【c++】为什么有了dll和.h,还需要包含lib
java·开发语言·c++
巴巴博一18 小时前
2026 最新:Trae / Cursor 一键接入 taste-skill 完整教程(让 AI 前端告别“AI 味”)
前端·ai·ai编程
kyriewen18 小时前
半夜三点线上崩了,AI替我背了锅——用AI排错,五分钟定位三年老bug
前端·javascript·ai编程
独隅19 小时前
CodeX + Visual Studio Code 联动的全面指南
开发语言·php
坚果派·白晓明19 小时前
【鸿蒙PC三方库移植适配框架解读系列】第一篇:Lycium C/C++ 三方库适配 — 概述与环境配置
c语言·开发语言·c++·harmonyos·开源鸿蒙·三方库·c/c++三方库