目录
一、ListView构造方法
主要以下几种方法:
- 常规方法,直接使用默认的构造方法
- ListView.builder
- ListView.separated
1.1 常规方法
ListView的常规方法:就是利用默认方法构造各个item,ListView有个children属性:传入多个widget:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
Widget build(BuildContext context) {
const title = 'ListView的使用';
return MaterialApp(
debugShowCheckedModeBanner: false,
title: title,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body:
MyHomeBody(),
);
}
}
class MyHomeBody extends StatelessWidget {
const MyHomeBody({super.key});
final TextStyle textStyle = const TextStyle(fontSize: 10, color: Colors.blue);
Widget build(BuildContext context) {
return ListView(
children: List<Widget>.generate(100, (i) => Text('列表 $i')),
);
}
}
运行效果图如下:
1.2 ListView.builder
List<Widget>.generate 会默认把所有子item全部创建出来,如果子item数量过多时,会影响页面的渲染时间,ListView.builder不会把所有子item创建出来,会在真正需要的时候构建出来,不会一开始全部初始化出来,适合数量很多item的场景:
void main() {
runApp(
MyApp(
items: List<String>.generate(10000, (i) => '列表 $i'),
),
);
}
class MyApp extends StatelessWidget {
final List<String> items;
const MyApp({super.key, required this.items});
// This widget is the root of your application.
Widget build(BuildContext context) {
const title = 'ListView的使用';
return MaterialApp(
debugShowCheckedModeBanner: false,
title: title,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
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]),
);
},
),
);
}
}
运行效果图如下:
1.3 ListView.separated
ListVIew.separated相比ListView.builder只是每项之间增加了一个分割符合:
void main() {
runApp(
MyApp(
items: List<String>.generate(10000, (i) => '列表 $i'),
),
);
}
class MyApp extends StatelessWidget {
final List<String> items;
const MyApp({super.key, required this.items});
// This widget is the root of your application.
Widget build(BuildContext context) {
const title = 'ListView的使用';
return MaterialApp(
debugShowCheckedModeBanner: false,
title: title,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body:
ListView.separated(
itemCount: items.length,
separatorBuilder: (context, index) => const Divider(),
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index]),
);
},
),
);
}
}
运行效果图如下:
二、自定义ListView样式和布局:
我们可以使用ListView.builder的itemBuilder属性来自定义列表项的样式和布局,下面一个例子是动态设置item布局背景
void main() {
runApp(
MyApp(
items: List<String>.generate(10000, (i) => '列表 $i'),
),
);
}
class MyApp extends StatelessWidget {
final List<String> items;
const MyApp({super.key, required this.items});
// This widget is the root of your application.
Widget build(BuildContext context) {
const title = 'ListView的使用';
return MaterialApp(
debugShowCheckedModeBanner: false,
title: title,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body:
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Container(
color: index % 2 == 0 ? Colors.grey[300] : Colors.red,
padding: const EdgeInsets.all(16),
child: Text(items[index]),
);
},
),
),
);
运行效果图如下:
三、ListView性能优化:
当使用ListView显示大量数据时,为了提高性能,推荐以下优化方式:
- 使用ListView.builder或ListView.separated来按需构建列表项,避免一次性构建所有的项。
- 使用ListView.separated并提供合适的分隔符构建方法,避免不必要的分隔符构建。
- 如果列表项固定是高度,请使用itemExtent属性来指定项的高度,避免动态计算高度带来的性能开销。
- 使用ScrollController来控制滚动,并使用addPostFrameCallback在构建完成后延迟加载数据。
总结:
上文我们介绍构建ListView常见的几种使用方法,以及简单的自定义布局和样式方法的例子,优化ListView性能方式方法,使用ListView推荐使用ListView.builder、ListView.separated。
Thanks:
Flutter可滚动组件(2):ListView基本使用