基础列表
显示数据列表是移动应用程序的基本模式。 Flutter包含部件,使列表变得轻而易举!
创建一个ListView
使用标准的ListView构造函数非常适合仅包含少量项目的列表。 我们还将使用内置的ListTile部件来为我们的项目提供一个可视结构。
new ListView( children:[ new ListTile( leading: new Icon(Icons.map), title: new Text('Map'), ), new ListTile( leading: new Icon(Icons.photo_album), title: new Text('Album'), ), new ListTile( leading: new Icon(Icons.phone), title: new Text('Phone'), ), ],);
完整例子
import 'package:flutter/material.dart';void main() => runApp(new MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final title = 'Basic List'; return new MaterialApp( title: title, home: new Scaffold( appBar: new AppBar( title: new Text(title), ), body: new ListView( children:[ new ListTile( leading: new Icon(Icons.map), title: new Text('Map'), ), new ListTile( leading: new Icon(Icons.photo_album), title: new Text('Album'), ), new ListTile( leading: new Icon(Icons.phone), title: new Text('Phone'), ), ], ), ), ); }}
创建一个水平列表
有时,您可能想要创建一个水平滚动而不是垂直滚动的列表。 部件支持开箱即用的水平列表。
我们将使用标准的ListView构造函数,通过横向scrollDirection,这将覆盖默认的垂直方向。
new ListView( // This next line does the trick. scrollDirection: Axis.horizontal, children:[ new Container( width: 160.0, color: Colors.red, ), new Container( width: 160.0, color: Colors.blue, ), new Container( width: 160.0, color: Colors.green, ), new Container( width: 160.0, color: Colors.yellow, ), new Container( width: 160.0, color: Colors.orange, ), ],)
完整例子
import 'package:flutter/material.dart';void main() => runApp(new MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final title = 'Horizontal List'; return new MaterialApp( title: title, home: new Scaffold( appBar: new AppBar( title: new Text(title), ), body: new Container( margin: new EdgeInsets.symmetric(vertical: 20.0), height: 200.0, child: new ListView( scrollDirection: Axis.horizontal, children:[ new Container( width: 160.0, color: Colors.red, ), new Container( width: 160.0, color: Colors.blue, ), new Container( width: 160.0, color: Colors.green, ), new Container( width: 160.0, color: Colors.yellow, ), new Container( width: 160.0, color: Colors.orange, ), ], ), ), ), ); }}
使用长列表
标准的构造函数适用于小列表。 为了处理包含大量项目的列表,最好使用构造函数。
虽然默认的ListView构造函数要求我们一次创建所有条目,但ListView.builder构造函数将在滚动到屏幕上时创建条目。
1.创建一个数据源
首先,我们需要一个数据源来处理。 例如,您的数据源可能是消息列表,搜索结果或商店中的产品。 大多数情况下,这些数据将来自互联网或数据库。
在这个例子中,我们将使用构造函数生成一个10000个字符串的列表。
final items = new List.generate(10000, (i) => "Item $i");
2.将数据源转换成部件
为了显示我们的字符串列表,我们需要将每个字符串呈现为一个部件!
这是ListView.builder将发挥作用的地方。 在我们的例子中,我们将在它自己的行上显示每个字符串。
new ListView.builder( itemCount: items.length, itemBuilder: (context, index) { return new ListTile( title: new Text('${items[index]}'), ); },);
完整例子
import 'package:flutter/foundation.dart';import 'package:flutter/material.dart';void main() { runApp(new MyApp( items: new List.generate(10000, (i) => "Item $i"), ));}class MyApp extends StatelessWidget { final List items; MyApp({Key key, @required this.items}) : super(key: key); @override Widget build(BuildContext context) { final title = 'Long List'; return new MaterialApp( title: title, home: new Scaffold( appBar: new AppBar( title: new Text(title), ), body: new ListView.builder( itemCount: items.length, itemBuilder: (context, index) { return new ListTile( title: new Text('${items[index]}'), ); }, ), ), ); }}
创建一个包含不同类型条目的列表
我们经常需要创建显示不同类型内容的列表。 例如,我们可能正在制作一个列表,其中显示一个标题,后面跟着与该标题相关的几个项目,后面是另一个标题,等等。
我们如何用Flutter创建这样一个结构?
路线
- 使用不同类型的条目创建数据源
- 将数据源转换为部件列表
1.使用不同类型的条目创建数据源
项目类型
为了在列表中表示不同类型的项目,我们需要为每种类型的项目定义一个类别。
在这个例子中,我们将在一个应用程序上显示一个标题,后面跟着五条消息。 因此,我们将创建三个类:ListItem,HeadingItem和MessageItem。
// The base class for the different types of items the List can containabstract class ListItem {}// A ListItem that contains data to display a headingclass HeadingItem implements ListItem { final String heading; HeadingItem(this.heading);}// A ListItem that contains data to display a messageclass MessageItem implements ListItem { final String sender; final String body; MessageItem(this.sender, this.body);}
创建项目列表
大多数情况下,我们会从互联网或本地数据库获取数据,并将这些数据转换为项目列表。对于这个例子,我们将生成一个项目列表来处理。 该列表将包含一个标题,后跟五个消息。 冲洗,重复。
final items = new List.generate( 1200, (i) => i % 6 == 0 ? new HeadingItem("Heading $i") : new MessageItem("Sender $i", "Message body $i"),);
2.将数据源转换为部件列表
为了处理将每个项目转换为部件,我们将使用ListView.builder构造函数。
一般来说,我们希望提供一个builder函数来检查我们正在处理的项目类型,并返回该类型项目的相应部件。
在这个例子中,使用is关键字来检查我们正在处理的项目类型可能非常方便。 速度很快,并会自动将每个项目转换为适当的类型。 但是,如果您更喜欢另一种模式,则有不同的方法可以解决此问题!
new ListView.builder( // Let the ListView know how many items it needs to build itemCount: items.length, // Provide a builder function. This is where the magic happens! We'll // convert each item into a Widget based on the type of item it is. itemBuilder: (context, index) { final item = items[index]; if (item is HeadingItem) { return new ListTile( title: new Text( item.heading, style: Theme.of(context).textTheme.headline, ), ); } else if (item is MessageItem) { return new ListTile( title: new Text(item.sender), subtitle: new Text(item.body), ); } },);
完整例子
import 'package:flutter/foundation.dart';import 'package:flutter/material.dart';void main() { runApp(new MyApp( items: new List.generate( 1000, (i) => i % 6 == 0 ? new HeadingItem("Heading $i") : new MessageItem("Sender $i", "Message body $i"), ), ));}class MyApp extends StatelessWidget { final List items; MyApp({Key key, @required this.items}) : super(key: key); @override Widget build(BuildContext context) { final title = 'Mixed List'; return new MaterialApp( title: title, home: new Scaffold( appBar: new AppBar( title: new Text(title), ), body: new ListView.builder( // Let the ListView know how many items it needs to build itemCount: items.length, // Provide a builder function. This is where the magic happens! We'll // convert each item into a Widget based on the type of item it is. itemBuilder: (context, index) { final item = items[index]; if (item is HeadingItem) { return new ListTile( title: new Text( item.heading, style: Theme.of(context).textTheme.headline, ), ); } else if (item is MessageItem) { return new ListTile( title: new Text(item.sender), subtitle: new Text(item.body), ); } }, ), ), ); }}// The base class for the different types of items the List can containabstract class ListItem {}// A ListItem that contains data to display a headingclass HeadingItem implements ListItem { final String heading; HeadingItem(this.heading);}// A ListItem that contains data to display a messageclass MessageItem implements ListItem { final String sender; final String body; MessageItem(this.sender, this.body);}
创建一个网格列表
在某些情况下,您可能希望将项目显示为网格,而不是显示下一个项目的普通列表。 对于这个任务,我们将使用部件。
开始使用网格的最简单方法是使用构造函数,因为它允许我们指定我们想要的行数或列数。
在这个例子中,我们将生成一个100个部件的列表,在列表中显示它们的索引。 这将帮助我们可视化GridView的工作原理。
new GridView.count( // Create a grid with 2 columns. If you change the scrollDirection to // horizontal, this would produce 2 rows. crossAxisCount: 2, // Generate 100 Widgets that display their index in the List children: new List.generate(100, (index) { return new Center( child: new Text( 'Item $index', style: Theme.of(context).textTheme.headline, ), ); }),);
完整例子
import 'package:flutter/material.dart';void main() { runApp(new MyApp());}class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final title = 'Grid List'; return new MaterialApp( title: title, home: new Scaffold( appBar: new AppBar( title: new Text(title), ), body: new GridView.count( // Create a grid with 2 columns. If you change the scrollDirection to // horizontal, this would produce 2 rows. crossAxisCount: 2, // Generate 100 Widgets that display their index in the List children: new List.generate(100, (index) { return new Center( child: new Text( 'Item $index', style: Theme.of(context).textTheme.headline, ), ); }), ), ), ); }}