前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter 构建完整应用手册-列表 顶

Flutter 构建完整应用手册-列表 顶

作者头像
南郭先生
发布2018-08-14 16:00:32
2.5K0
发布2018-08-14 16:00:32
举报
文章被收录于专栏:Google DartGoogle Dart

基础列表

显示数据列表是移动应用程序的基本模式。 Flutter包含ListView部件,使列表变得轻而易举!

创建一个ListView

使用标准的ListView构造函数非常适合仅包含少量项目的列表。 我们还将使用内置的ListTile部件来为我们的项目提供一个可视结构。

代码语言:javascript
复制
new ListView(
  children: <Widget>[
    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'),
    ),
  ],
);

完整例子

代码语言:javascript
复制
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: <Widget>[
            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部件支持开箱即用的水平列表。

我们将使用标准的ListView构造函数,通过横向scrollDirection,这将覆盖默认的垂直方向。

代码语言:javascript
复制
new ListView(
  // This next line does the trick.
  scrollDirection: Axis.horizontal,
  children: <Widget>[
    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,
    ),
  ],
)

完整例子

代码语言:javascript
复制
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: <Widget>[
              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构造函数。

虽然默认的ListView构造函数要求我们一次创建所有条目,但ListView.builder构造函数将在滚动到屏幕上时创建条目。

1.创建一个数据源

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

在这个例子中,我们将使用List.generate构造函数生成一个10000个字符串的列表。

代码语言:javascript
复制
final items = new List<String>.generate(10000, (i) => "Item $i");

2.将数据源转换成部件

为了显示我们的字符串列表,我们需要将每个字符串呈现为一个部件!

这是ListView.builder将发挥作用的地方。 在我们的例子中,我们将在它自己的行上显示每个字符串。

代码语言:javascript
复制
new ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return new ListTile(
      title: new Text('${items[index]}'),
    );
  },
);

完整例子

代码语言:javascript
复制
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  final List<String> 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. 使用不同类型的条目创建数据源
  2. 将数据源转换为部件列表

1.使用不同类型的条目创建数据源

项目类型

为了在列表中表示不同类型的项目,我们需要为每种类型的项目定义一个类别。

在这个例子中,我们将在一个应用程序上显示一个标题,后面跟着五条消息。 因此,我们将创建三个类:ListItem,HeadingItem和MessageItem。

代码语言:javascript
复制
// The base class for the different types of items the List can contain
abstract class ListItem {}

// A ListItem that contains data to display a heading
class HeadingItem implements ListItem {
  final String heading;

  HeadingItem(this.heading);
}

// A ListItem that contains data to display a message
class MessageItem implements ListItem {
  final String sender;
  final String body;

  MessageItem(this.sender, this.body);
}

创建项目列表 大多数情况下,我们会从互联网或本地数据库获取数据,并将这些数据转换为项目列表。

对于这个例子,我们将生成一个项目列表来处理。 该列表将包含一个标题,后跟五个消息。 冲洗,重复。

代码语言:javascript
复制
final items = new List<ListItem>.generate(
  1200,
  (i) => i % 6 == 0
      ? new HeadingItem("Heading $i")
      : new MessageItem("Sender $i", "Message body $i"),
);

2.将数据源转换为部件列表

为了处理将每个项目转换为部件,我们将使用ListView.builder构造函数。

一般来说,我们希望提供一个builder函数来检查我们正在处理的项目类型,并返回该类型项目的相应部件。

在这个例子中,使用is关键字来检查我们正在处理的项目类型可能非常方便。 速度很快,并会自动将每个项目转换为适当的类型。 但是,如果您更喜欢另一种模式,则有不同的方法可以解决此问题!

代码语言:javascript
复制
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),
      );
    }
  },
);

完整例子

代码语言:javascript
复制
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp(
    items: new List<ListItem>.generate(
      1000,
      (i) => i % 6 == 0
          ? new HeadingItem("Heading $i")
          : new MessageItem("Sender $i", "Message body $i"),
    ),
  ));
}

class MyApp extends StatelessWidget {
  final List<ListItem> 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 contain
abstract class ListItem {}

// A ListItem that contains data to display a heading
class HeadingItem implements ListItem {
  final String heading;

  HeadingItem(this.heading);
}

// A ListItem that contains data to display a message
class MessageItem implements ListItem {
  final String sender;
  final String body;

  MessageItem(this.sender, this.body);
}

创建一个网格列表

在某些情况下,您可能希望将项目显示为网格,而不是显示下一个项目的普通列表。 对于这个任务,我们将使用GridView部件。

开始使用网格的最简单方法是使用GridView.count构造函数,因为它允许我们指定我们想要的行数或列数。

在这个例子中,我们将生成一个100个部件的列表,在列表中显示它们的索引。 这将帮助我们可视化GridView的工作原理。

代码语言:javascript
复制
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,
      ),
    );
  }),
);

完整例子

代码语言:javascript
复制
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,
              ),
            );
          }),
        ),
      ),
    );
  }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基础列表
    • 创建一个ListView
      • 完整例子
      • 创建一个水平列表
        • 完整例子
        • 使用长列表
          • 1.创建一个数据源
            • 2.将数据源转换成部件
              • 完整例子
              • 创建一个包含不同类型条目的列表
                • 1.使用不同类型的条目创建数据源
                  • 2.将数据源转换为部件列表
                    • 完整例子
                    • 创建一个网格列表
                      • 完整例子
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档