Flutter---ListView

核心功能

用于显示​​可滚动的线性列表​​(垂直/水平)

支持​​懒加载​ ​(builder系列)和​​静态列表​ ​(children

内置​​滚动物理效果​​(弹性和边界效果)

四种构造方法

ListView():一次性构建所有子项

ListView.builder():按需构建子项,性能最优

ListView.separated():自动添加分隔组件

ListView.custom():使用 SliverChildDelegate

ListView的基础列表

Dart 复制代码
ListView.builder(
  itemCount: data.length,
  itemBuilder: (ctx, index) {
    return ListTile(
      title: Text(data[index].title),
      subtitle: Text(data[index].subtitle),
    );
  },
)

构建列表的数据流

①初始化列表数据

②ListView.builder初始化

③读取 itemCount: users.length(值为10)

④框架传入当前的 contextindex

⑤通过 users[index]获取对应数据

⑥返回构建好的 CardWidget

当用户点击列表时

①框架检测滚动位置变化

②动态计算新的 index范围(如滚动后需要显示index 2-5)

③销毁已离开屏幕的列表项(如index 0-1)

④调用 itemBuilder构建新进入屏幕的项(如index 4-5)

当用户点击列表项时

①触发点击事件

②获取当前 contextuser.name

③创建并显示SnackBar

④点击"关闭"按钮时销毁SnackBar

代码实例

main.dart

Dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
      ),
      home: const MyHomePage(title: '水果用户列表'),
    );
  }
}

//列表项的类
class User {
  final String name;
  final String email;
  final String imageAsset;  // 存储本地图片路径
  //构造函数
  User({
    required this.name,
    required this.email,
    required this.imageAsset,
  });
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  // 子项数据,每个用户关联不同的本地图片
  final List<User> users = [
    User(
      name: "苹果用户",
      email: "apple@example.com",
      imageAsset: 'assets/images/apple.png',
    ),
    User(
      name: "香蕉用户",
      email: "banana@example.com",
      imageAsset: 'assets/images/banana.png',
    ),
    User(
      name: "樱桃用户",
      email: "cherry@example.com",
      imageAsset: 'assets/images/cherry.png',
    ),
    User(
      name: "芒果用户",
      email: "mango@example.com",
      imageAsset: 'assets/images/mango.png',
    ),
    User(
      name: "菠萝用户",
      email: "pineapple@example.com",
      imageAsset: 'assets/images/pineapple.png',
    ),
    User(
      name: "苹果用户",
      email: "apple@example.com",
      imageAsset: 'assets/images/apple.png',
    ),
    User(
      name: "香蕉用户",
      email: "banana@example.com",
      imageAsset: 'assets/images/banana.png',
    ),
    User(
      name: "樱桃用户",
      email: "cherry@example.com",
      imageAsset: 'assets/images/cherry.png',
    ),
    User(
      name: "芒果用户",
      email: "mango@example.com",
      imageAsset: 'assets/images/mango.png',
    ),
    User(
      name: "菠萝用户",
      email: "pineapple@example.com",
      imageAsset: 'assets/images/pineapple.png',
    ),
  ];

  //UI建造
  @override
  Widget build(BuildContext context) {
    return Scaffold(

      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
        centerTitle: true,//居中标题
      ),

      body: ListView.builder(//构造列表
        itemCount: users.length,//列表项总数
        //动态构建每个列表项的UI
        itemBuilder: (context, index) {//框架自动传递index

          final user = users[index];//用index取User对象数据,通过 index实现 ListView与数据的间接关联

          return Card(//Card 容器
            margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),//外边距
            child: ListTile(
              leading: Image.asset( //左侧图标
                user.imageAsset,
                width: 50,
                height: 50,
                errorBuilder: (context, error, stackTrace) {
                  return const Icon(Icons.error); // 图片加载失败时显示错误图标
                },
              ),
              title: Text(user.name),//第一个text
              subtitle: Text(user.email),//第二个text
              trailing: const Icon(Icons.arrow_forward),//右侧箭头图标
              //点击事件
              onTap: () {
                ScaffoldMessenger.of(context).showSnackBar( //SnackBar底部提示条
                  SnackBar(
                    content: Text("选择了: ${user.name}"), //文本提示
                    action: SnackBarAction(
                      label: '关闭',
                      onPressed: () {},
                    ),
                  ),
                );
              },
            ),
          );
        },

      ),
    );
  }
}
相关推荐
盆鱼宴之武冈分宴9 小时前
flutter openharmony项目新手从0到1的保姆级教程
flutter·openharmony
程序员老刘21 小时前
Dart的宏取消了,期待3年的功能,说没就没了?
flutter·客户端·dart
_大学牲1 天前
Flutter 之魂 GetX🔥(三)深入掌握依赖管理
前端·flutter
西西学代码1 天前
Flutter---showCupertinoDialog
java·前端·flutter
爱吃水蜜桃的奥特曼1 天前
玩Android Flutter版本,通过项目了解Flutter项目快速搭建开发
android·flutter
西西学代码1 天前
Flutter---带输入框的对话框
flutter
_阿南_1 天前
flutter在Xcode26打包的iOS26上全屏支持右滑的问题
flutter·ios·xcode
西西学代码1 天前
Flutter---坐标网格图标
前端·javascript·flutter