Skip to main content

处理长列表

标准的ListView 构造函数适用于小型列表。要处理包含大量项目的列表,最好使用ListView.builder 构造函数。

与需要一次性创建所有项目的默认 ListView 构造函数相比,ListView.builder() 构造函数会在项目滚动到屏幕上时创建它们。

1. 创建数据源

#

首先,您需要一个数据源。例如,您的数据源可能是消息列表、搜索结果或商店中的产品。大多数情况下,这些数据来自互联网或数据库。

在此示例中,使用List.generate 构造函数生成 10,000 个字符串的列表。

dart
List<String>.generate(10000, (i) => 'Item $i'),

2. 将数据源转换为小部件

#

要显示字符串列表,请使用 ListView.builder() 将每个字符串呈现为小部件。在此示例中,在单独的行上显示每个字符串。

dart
ListView.builder(
  itemCount: items.length,
  prototypeItem: ListTile(
    title: Text(items.first),
  ),
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(items[index]),
    );
  },
)

交互式示例

#
import 'package:flutter/material.dart';

void main() {
  runApp(
    MyApp(
      items: List<String>.generate(10000, (i) => 'Item $i'),
    ),
  );
}

class MyApp extends StatelessWidget {
  final List<String> items;

  const MyApp({super.key, required this.items});

  @override
  Widget build(BuildContext context) {
    const title = '长列表';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: const Text(title),
        ),
        body: ListView.builder(
          itemCount: items.length,
          prototypeItem: ListTile(
            title: Text(items.first),
          ),
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(items[index]),
            );
          },
        ),
      ),
    );
  }
}

子项大小

#

要指定每个项目的范围,您可以使用prototypeItemitemExtentitemExtentBuilder

指定任一参数都比让子项确定其自身范围更有效率,因为滚动机制可以利用对子项范围的预知来节省工作,例如当滚动位置发生剧烈变化时。

如果您的列表具有固定大小的项目,请使用prototypeItemitemExtent

如果您的列表具有不同大小的项目,请使用itemExtentBuilder