在 Flutter 中,列表(List)和网格(Grid)是非常常用的布局方式,尤其适用于展示大量数据项。Flutter 提供了强大的 ListView 和 GridView 小部件来实现这些布局。下面详细介绍如何使用 ListView 和 GridView,并提供相关的示例代码。
列表(ListView)
ListView 是一个滚动方向为垂直或水平的可滚动列表,它适用于展示大量相同类型的项目。ListView 有多种构建方法,包括静态列表、动态列表和分组列表。
1. 静态列表
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ListView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ListView Demo'),
),
body: ListView(
children: <Widget>[
ListTile(
leading: Icon(Icons.map),
title: Text('Map'),
),
ListTile(
leading: Icon(Icons.photo_album),
title: Text('Album'),
),
ListTile(
leading: Icon(Icons.phone),
title: Text('Phone'),
),
],
),
);
}
}
2. 动态列表(基于数据源)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ListView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
final List<String> items = List<String>.generate(100, (i) => "Item $i");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ListView Demo'),
),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${items[index]}'),
);
},
),
);
}
}
3. 分组列表(使用 ListView.separated)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ListView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
final List<String> items = List<String>.generate(100, (i) => "Item $i");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ListView Demo'),
),
body: ListView.separated(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${items[index]}'),
);
},
separatorBuilder: (context, index) {
return Divider();
},
),
);
}
}
网格(GridView)
GridView 是一个可滚动的2D网格列表,适用于展示一系列数据项。GridView 提供了多种创建方法,包括固定行列数的网格和基于子项大小的网格。
1. 基于固定行列数的网格
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GridView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GridView Demo'),
),
body: GridView.count(
crossAxisCount: 2, // 每行显示的列数
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline6,
),
);
}),
),
);
}
}
2. 基于子项大小的网格
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GridView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
final List<String> items = List<String>.generate(100, (i) => "Item $i");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GridView Demo'),
),
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, // 每行显示的列数
),
itemCount: items.length,
itemBuilder: (context, index) {
return Card(
color: Colors.blueAccent,
child: Center(
child: Text(
items[index],
style: TextStyle(color: Colors.white),
),
),
);
},
),
);
}
}
3. 使用 GridView.extent 基于最大宽度的网格
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GridView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
final List<String> items = List<String>.generate(100, (i) => "Item $i");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GridView Demo'),
),
body: GridView.extent(
maxCrossAxisExtent: 150.0, // 每个子项的最大宽度
children: List.generate(100, (index) {
return Card(
color: Colors.blueAccent,
child: Center(
child: Text(
items[index],
style: TextStyle(color: Colors.white),
),
),
);
}),
),
);
}
}
总结
通过上述示例,你可以看到 Flutter 提供了多种方法来实现列表和网格布局。ListView 适用于展示线性排列的数据,而 GridView 适用于展示二维网格布局的数据。根据你的具体需求选择合适的布局方式,可以大大提高应用的可用性和用户体验。