跳到主内容

Flutter 中的布局

了解 Flutter 的布局机制以及如何构建你的应用的布局。

概述

#

Flutter 布局机制的核心是 Widget。在 Flutter 中,几乎所有东西都是 Widget——甚至布局模型也是 Widget。你在 Flutter 应用中看到的所有图像、图标和文本都是 Widget。但你看不到的东西也是 Widget,例如排列、约束和对齐可见 Widget 的行、列和网格。你通过组合 Widget 来构建更复杂的 Widget,从而创建布局。

概念示例

#

在下面的示例中,第一张截图显示了带有标签的三个图标,第二张截图包含行和列的视觉布局。在第二张截图中,debugPaintSizeEnabled 设置为 true,以便你可以看到视觉布局。

Sample layout
Sample layout with visual debugging

这是前一个示例的 Widget 树的图表

Node tree

其中大部分应该如你所料,但你可能想知道容器(显示为粉色)。 Container 是一个 Widget 类,允许你自定义其子 Widget。当你想要添加填充、边距、边框或背景颜色时,可以使用 Container,仅举其几项功能。

每个 Text Widget 放置在一个 Container 中以添加边距。整个 Row 也放置在一个 Container 中,以在行周围添加填充。

UI 的其余部分由属性控制。使用其 color 属性设置 Icon 的颜色。使用 Text.style 属性设置字体、颜色、粗细等。列和行具有属性,允许你指定其子项在垂直或水平方向上如何对齐,以及子项应占用多少空间。

布局一个 Widget

#

如何在 Flutter 中布局单个 Widget?本节向你展示了如何创建和显示一个简单的 Widget。它还显示了一个简单的 Hello World 应用的完整代码。

在 Flutter 中,只需几个步骤就可以将文本、图标或图像放在屏幕上。

1. 选择一个布局 Widget

#

根据你希望如何对齐或约束可见的 Widget,从各种 布局 Widget 中进行选择,因为这些特性通常会传递给包含的 Widget。

例如,你可以使用 Center 布局 Widget 水平和垂直居中一个可见的 Widget

dart
Center(
  // Content to be centered here.
)

2. 创建一个可见的 Widget

#

选择一个 可见的 Widget 用于你的应用,以包含可见元素,例如 文本图像图标

例如,你可以使用 Text Widget 显示一些文本

dart
Text('Hello World')

3. 将可见的 Widget 添加到布局 Widget

#

所有布局 Widget 都有以下两种之一

  • 如果它们接受单个子项,则具有 child 属性——例如,CenterContainer
  • 如果它们接受 Widget 列表,则具有 children 属性——例如,RowColumnListViewStack

Text Widget 添加到 Center Widget

dart
const Center(
  child: Text('Hello World'),
),

4. 将布局 Widget 添加到页面

#

Flutter 应用本身就是一个 Widget,并且大多数 Widget 都有一个 build() 方法。在应用的 build() 方法中实例化并返回 Widget 会显示该 Widget。

对于通用应用,你可以将 Container Widget 添加到应用的 build() 方法

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(color: Colors.white),
      child: const Center(
        child: Text(
          'Hello World',
          textDirection: TextDirection.ltr,
          style: TextStyle(fontSize: 32, color: Colors.black87),
        ),
      ),
    );
  }
}

默认情况下,通用应用不包含 AppBar、标题或背景颜色。如果你希望在通用应用中拥有这些功能,则必须自己构建它们。此应用将背景颜色更改为白色,并将文本更改为深灰色,以模拟 Material 应用。

对于 Material 应用,你可以使用 Scaffold Widget;它提供默认的横幅、背景颜色,并具有用于添加抽屉、小吃栏和底部表单的 API。然后,你可以将 Center Widget 直接添加到主页的 body 属性中。

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    const String appTitle = 'Flutter layout demo';
    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(title: const Text(appTitle)),
        body: const Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}

要创建一个 Cupertino 应用,请使用 CupertinoAppCupertinoPageScaffold Widget。

Material 不同,它不提供默认的横幅或背景颜色。你需要自己设置这些颜色。

  • 要设置默认颜色,请将配置的 CupertinoThemeData 传递到你的应用的 theme 属性。

  • 要在应用的顶部添加 iOS 样式的导航栏,请将 CupertinoNavigationBar Widget 添加到支架的 navigationBar 属性。你可以使用 CupertinoColors 提供的颜色来配置你的 Widget,以匹配 iOS 设计。

  • 要布局应用的 body,请使用所需的 Widget(例如 CenterColumn)作为其值设置支架的 child 属性。

要了解你可以添加的其他 UI 组件,请查看 Cupertino 库

dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const CupertinoApp(
      title: 'Flutter layout demo',
      theme: CupertinoThemeData(
        brightness: Brightness.light,
        primaryColor: CupertinoColors.systemBlue,
      ),
      home: CupertinoPageScaffold(
        navigationBar: CupertinoNavigationBar(
          backgroundColor: CupertinoColors.systemGrey,
          middle: Text('Flutter layout demo'),
        ),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [Text('Hello World')],
          ),
        ),
      ),
    );
  }
}

5. 运行你的应用

#

在添加了 Widget 后,运行你的应用。运行应用时,你应该看到 Hello World

应用源代码

Screenshot of app displaying Hello World

垂直和水平布局多个 Widget

#

最常见的布局模式之一是水平或垂直排列 Widget。你可以使用 Row Widget 水平排列 Widget,并使用 Column Widget 垂直排列 Widget。

要在 Flutter 中创建行或列,你将一个子 Widget 列表添加到 RowColumn Widget。反过来,每个子项本身可以是一个行或列,依此类推。以下示例显示了如何在行或列内嵌套行或列。

此布局组织为 Row。该行包含两个子项:左侧的列和右侧的图像

Screenshot with callouts showing the row containing two children

左侧列的 Widget 树嵌套了行和列。

Diagram showing a left column broken down to its sub-rows and sub-columns

你将在 嵌套行和列 中实现 Pavlova 的一些布局代码。

对齐 Widget

#

你使用 mainAxisAlignmentcrossAxisAlignment 属性控制行或列如何对其子项进行对齐。对于行,主轴水平运行,交叉轴垂直运行。对于列,主轴垂直运行,交叉轴水平运行。

Diagram showing the main axis and cross axis for a row
Diagram showing the main axis and cross axis for a column

MainAxisAlignmentCrossAxisAlignment 枚举提供各种常量,用于控制对齐方式。

在以下示例中,每张图像的宽度均为 100 像素。渲染框(在本例中为整个屏幕)的宽度大于 300 像素,因此将主轴对齐方式设置为 spaceEvenly 会在每张图像之间、之前和之后均匀地分配剩余的水平空间。

dart
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Image.asset('images/pic1.jpg'),
    Image.asset('images/pic2.jpg'),
    Image.asset('images/pic3.jpg'),
  ],
);
Row with 3 evenly spaced images

应用源码: row_column

列的工作方式与行相同。以下示例显示包含 3 张图像的列,每张图像的高度均为 100 像素。渲染框的高度(在本例中为整个屏幕)大于 300 像素,因此将主轴对齐方式设置为 spaceEvenly 会在每张图像之间、上方和下方均匀地分配剩余的垂直空间。

dart
Column(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Image.asset('images/pic1.jpg'),
    Image.asset('images/pic2.jpg'),
    Image.asset('images/pic3.jpg'),
  ],
);
Column showing 3 images spaced evenly

应用源码: row_column

调整 Widget 大小

#

当布局太大而无法适应设备时,受影响的边缘会出现黄色和黑色条纹图案。这里有一个 示例,展示了一个过宽的行。

Overly-wide row

可以使用 Expanded 部件将部件的大小调整为适应行或列。要修复上一个示例中行中的图像过宽的问题,请使用 Expanded 部件包装每张图像。

dart
Row(
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Expanded(child: Image.asset('images/pic1.jpg')),
    Expanded(child: Image.asset('images/pic2.jpg')),
    Expanded(child: Image.asset('images/pic3.jpg')),
  ],
);
Row of 3 images that are too wide, but each is constrained to take only 1/3 of the space

应用源码: sizing

也许您希望某个部件占据与其兄弟部件两倍的空间。为此,请使用 Expanded 部件的 flex 属性,该属性是一个整数,用于确定部件的弹性因子。默认弹性因子为 1。以下代码将中间图像的弹性因子设置为 2。

dart
Row(
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Expanded(child: Image.asset('images/pic1.jpg')),
    Expanded(flex: 2, child: Image.asset('images/pic2.jpg')),
    Expanded(child: Image.asset('images/pic3.jpg')),
  ],
);
Row of 3 images with the middle image twice as wide as the others

应用源码: sizing

打包 Widget

#

默认情况下,行或列会尽可能多地占据主轴上的空间,但如果您希望将子部件紧密地排列在一起,请将其 mainAxisSize 设置为 MainAxisSize.min。以下示例使用此属性将星形图标打包在一起。

dart
Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    const Icon(Icons.star, color: Colors.black),
    const Icon(Icons.star, color: Colors.black),
  ],
)
Row of 5 stars, packed together in the middle of the row

应用源码: pavlova

嵌套行和列

#

布局框架允许您根据需要将行和列嵌套在行和列中。让我们查看以下布局中轮廓部分的的代码。

Screenshot of the pavlova app, with the ratings and icon rows outlined in red

轮廓部分由两行实现。评分行包含五个星级和一个评论数。图标行包含三列图标和文本。

评分行的部件树

Ratings row widget tree

ratings 变量创建一个包含较小的一行 5 星图标和文本的行。

dart
final stars = Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    const Icon(Icons.star, color: Colors.black),
    const Icon(Icons.star, color: Colors.black),
  ],
);

final ratings = Container(
  padding: const EdgeInsets.all(20),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      stars,
      const Text(
        '170 Reviews',
        style: TextStyle(
          color: Colors.black,
          fontWeight: FontWeight.w800,
          fontFamily: 'Roboto',
          letterSpacing: 0.5,
          fontSize: 20,
        ),
      ),
    ],
  ),
);

位于评分行下方的图标行包含 3 列;每列包含一个图标和两行文本,如其部件树所示。

Icon widget tree

iconList 变量定义图标行。

dart
const descTextStyle = TextStyle(
  color: Colors.black,
  fontWeight: FontWeight.w800,
  fontFamily: 'Roboto',
  letterSpacing: 0.5,
  fontSize: 18,
  height: 2,
);

// DefaultTextStyle.merge() allows you to create a default text
// style that is inherited by its child and all subsequent children.
final iconList = DefaultTextStyle.merge(
  style: descTextStyle,
  child: Container(
    padding: const EdgeInsets.all(20),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Column(
          children: [
            Icon(Icons.kitchen, color: Colors.green[500]),
            const Text('PREP:'),
            const Text('25 min'),
          ],
        ),
        Column(
          children: [
            Icon(Icons.timer, color: Colors.green[500]),
            const Text('COOK:'),
            const Text('1 hr'),
          ],
        ),
        Column(
          children: [
            Icon(Icons.restaurant, color: Colors.green[500]),
            const Text('FEEDS:'),
            const Text('4-6'),
          ],
        ),
      ],
    ),
  ),
);

leftColumn 变量包含评分行和图标行,以及描述 Pavlova 的标题和文本。

dart
final leftColumn = Container(
  padding: const EdgeInsets.fromLTRB(20, 30, 20, 20),
  child: Column(children: [titleText, subTitle, ratings, iconList]),
);

左列放置在 SizedBox 中以限制其宽度。最后,UI 使用整个行(包含左列和图像)在 Card 中构建。

Pavlova 图像 来自 Pixabay。您可以使用 Image.network() 嵌入来自网络的图像,但对于此示例,图像已保存到项目的 images 目录中,添加到 pubspec 文件 中,并使用 Images.asset() 访问。有关更多信息,请参阅 添加资源和图像

dart
body: Center(
  child: Container(
    margin: const EdgeInsets.fromLTRB(0, 40, 0, 30),
    height: 600,
    child: Card(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(width: 440, child: leftColumn),
          mainImage,
        ],
      ),
    ),
  ),
),

应用源码: pavlova


常用的布局 Widget

#

Flutter 具有丰富的布局部件库。以下是一些最常用的部件。目的是让您尽快上手,而不是让您不堪重负地了解完整的列表。有关其他可用部件的信息,请参阅 部件目录,或在 API 参考文档 中使用搜索框。此外,API 文档中的部件页面通常会提出有关可能更适合您需求的类似部件的建议。

以下部件分为两类:来自 widgets 库 的标准部件,以及来自 Material 库 的专用部件。任何应用程序都可以使用 widgets 库,但只有 Material 应用程序才能使用 Material Components 库。

容器

为部件添加填充、边距、边框、背景色或其他装饰。

GridView

将部件布局为可滚动的网格。

ListView

将部件布局为可滚动的列表。

层叠布局

将一个部件叠放在另一个部件之上。

Scaffold

提供一个结构化的布局框架,其中包含用于常见 Material Design 应用程序元素的插槽。

AppBar

创建一个通常显示在屏幕顶部的水平栏。

Card

将相关信息组织到一个带有圆角和阴影的框中。

ListTile

将最多三行文本以及可选的引导和尾随图标组织到一行中。

CupertinoPageScaffold

为 iOS 风格的页面提供基本的布局结构。

CupertinoNavigationBar

在屏幕顶部创建一个 iOS 风格的导航栏。

CupertinoSegmentedControl

创建一个用于选择的分段控件。

CupertinoTabBarCupertinoTabScaffold

创建典型的 iOS 底部的选项卡栏。

容器

#

许多布局会大量使用 Container 来使用填充分隔部件,或添加边框或边距。您可以通过将整个布局放置在 Container 中并更改其背景色或图像来更改设备的背景。

摘要 (Container)

#
  • 添加填充、边距、边框
  • 更改背景色或图像
  • 包含单个子部件,但该子部件可以是 RowColumn,甚至是部件树的根。
Diagram showing: margin, border, padding, and content

示例 (Container)

#

此布局由一个包含两行、每行包含 2 张图像的列组成。 Container 用于将列的背景色更改为较浅的灰色。

dart
Widget _buildImageColumn() {
  return Container(
    decoration: const BoxDecoration(color: Colors.black26),
    child: Column(children: [_buildImageRow(1), _buildImageRow(3)]),
  );
}
Screenshot showing 2 rows, each containing 2 images

Container 还用于为每张图像添加圆角边框和边距

dart
Widget _buildDecoratedImage(int imageIndex) => Expanded(
  child: Container(
    decoration: BoxDecoration(
      border: Border.all(width: 10, color: Colors.black38),
      borderRadius: const BorderRadius.all(Radius.circular(8)),
    ),
    margin: const EdgeInsets.all(4),
    child: Image.asset('images/pic$imageIndex.jpg'),
  ),
);

Widget _buildImageRow(int imageIndex) => Row(
  children: [
    _buildDecoratedImage(imageIndex),
    _buildDecoratedImage(imageIndex + 1),
  ],
);

您可以在 教程 中找到更多 Container 示例。

应用源码: container


GridView

#

使用 GridView 将部件布局为二维列表。GridView 提供两个预制列表,或者您可以构建自己的自定义网格。当 GridView 检测到其内容太大而无法适应渲染框时,它会自动滚动。

摘要 (GridView)

#
  • 将部件布局为网格
  • 检测到列内容超过渲染框并自动提供滚动
  • 构建自己的自定义网格,或使用提供的网格之一
    • GridView.count 允许您指定列数
    • GridView.extent 允许您指定瓷片的最大像素宽度

示例 (GridView)

#
A 3-column grid of photos

使用 GridView.extent 创建一个瓷片最大宽度为 150 像素的网格。

应用源码: grid_and_list

A 2 column grid with footers

使用 GridView.count 创建一个在纵向模式下为 2 列,在横向模式下为 3 列的网格。标题是通过为每个 GridTile 设置 footer 属性创建的。

Dart 代码: grid_list_demo.dart

dart
Widget _buildGrid() => GridView.extent(
  maxCrossAxisExtent: 150,
  padding: const EdgeInsets.all(4),
  mainAxisSpacing: 4,
  crossAxisSpacing: 4,
  children: _buildGridTileList(30),
);

// The images are saved with names pic0.jpg, pic1.jpg...pic29.jpg.
// The List.generate() constructor allows an easy way to create
// a list when objects have a predictable naming pattern.
List<Widget> _buildGridTileList(int count) =>
    List.generate(count, (i) => Image.asset('images/pic$i.jpg'));

ListView

#

ListView 是一种类似于列的部件,当其内容太大而无法适应其渲染框时,会自动提供滚动。

摘要 (ListView)

#
  • 一个专门的 Column,用于组织一个盒子列表
  • 可以水平或垂直布局
  • 检测到其内容不合适并提供滚动
  • Column 的可配置性低,但更易于使用并支持滚动

示例 (ListView)

#
ListView containing movie theaters and restaurants

使用 ListView 使用 ListTile 显示业务列表。Divider 将剧院与餐馆分隔开。

应用源码: grid_and_list

ListView containing shades of blue

使用 ListView 显示来自 ColorsMaterial 2 设计调色板 的特定颜色系列。

Dart 代码: colors_demo.dart

dart
Widget _buildList() {
  return ListView(
    children: [
      _tile('CineArts at the Empire', '85 W Portal Ave', Icons.theaters),
      _tile('The Castro Theater', '429 Castro St', Icons.theaters),
      _tile('Alamo Drafthouse Cinema', '2550 Mission St', Icons.theaters),
      _tile('Roxie Theater', '3117 16th St', Icons.theaters),
      _tile(
        'United Artists Stonestown Twin',
        '501 Buckingham Way',
        Icons.theaters,
      ),
      _tile('AMC Metreon 16', '135 4th St #3000', Icons.theaters),
      const Divider(),
      _tile('K\'s Kitchen', '757 Monterey Blvd', Icons.restaurant),
      _tile('Emmy\'s Restaurant', '1923 Ocean Ave', Icons.restaurant),
      _tile('Chaiya Thai Restaurant', '272 Claremont Blvd', Icons.restaurant),
      _tile('La Ciccia', '291 30th St', Icons.restaurant),
    ],
  );
}

ListTile _tile(String title, String subtitle, IconData icon) {
  return ListTile(
    title: Text(
      title,
      style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
    ),
    subtitle: Text(subtitle),
    leading: Icon(icon, color: Colors.blue[500]),
  );
}

层叠布局

#

使用 Stack 将部件排列在基本部件之上,通常是图像。部件可以完全或部分覆盖基本部件。

摘要 (Stack)

#
  • 用于与其他部件重叠的部件
  • 列表中的第一个部件是基本部件;后续部件覆盖在该基本部件之上
  • Stack 的内容无法滚动
  • 您可以选择剪裁超出渲染框的子部件

示例 (Stack)

#
Circular avatar image with a label

使用 Stack 将一个 Container(在其 Text 上显示半透明黑色背景)叠加在 CircleAvatar 之上。Stack 使用 alignment 属性和 Alignment 对文本进行偏移。

应用源码: card_and_stack

An image with a icon overlaid on top

使用 Stack 将一个图标叠加在图像之上。

Dart 代码: bottom_navigation_demo.dart

dart
Widget _buildStack() {
  return Stack(
    alignment: const Alignment(0.6, 0.6),
    children: [
      const CircleAvatar(
        backgroundImage: AssetImage('images/pic.jpg'),
        radius: 100,
      ),
      Container(
        decoration: const BoxDecoration(color: Colors.black45),
        child: const Text(
          'Mia B',
          style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.bold,
            color: Colors.white,
          ),
        ),
      ),
    ],
  );
}

Card

#

一个 Card,来自 Material 库,包含相关的信息片段,并且可以由几乎任何小部件组成,但通常与 ListTile 一起使用。Card 只有一个子组件,但其子组件可以是一个列、行、列表、网格或其他支持多个子组件的小部件。默认情况下,Card 的大小缩小到 0x0 像素。您可以使用 SizedBox 来约束卡片的大小。

在 Flutter 中,Card 具有略微圆角的边框和阴影,使其具有 3D 效果。更改 Cardelevation 属性可以控制阴影效果。例如,将 elevation 设置为 24,可以使 Card 在视觉上远离表面,并使阴影更加分散。有关支持的 elevation 值列表,请参阅 ElevationMaterial 指南 中。

摘要 (Card)

#
  • 实现一个 Material 卡片
  • 用于呈现相关的信息片段
  • 接受一个子组件,但该子组件可以是 RowColumn 或其他包含子组件列表的小部件
  • 以圆角和阴影显示
  • Card 的内容无法滚动
  • 来自 Material 库

示例 (Card)

#
Card containing 3 ListTiles

一个包含 3 个 ListTile 的 Card,并通过将其包装在 SizedBox 中来确定其大小。一个 Divider 分隔了第一个和第二个 ListTiles

应用源码: card_and_stack

Tappable card containing an image and multiple forms of text

一个包含图像和文本的 Card。

Dart 代码: cards_demo.dart

dart
Widget _buildCard() {
  return SizedBox(
    height: 210,
    child: Card(
      child: Column(
        children: [
          ListTile(
            title: const Text(
              '1625 Main Street',
              style: TextStyle(fontWeight: FontWeight.w500),
            ),
            subtitle: const Text('My City, CA 99984'),
            leading: Icon(Icons.restaurant_menu, color: Colors.blue[500]),
          ),
          const Divider(),
          ListTile(
            title: const Text(
              '(408) 555-1212',
              style: TextStyle(fontWeight: FontWeight.w500),
            ),
            leading: Icon(Icons.contact_phone, color: Colors.blue[500]),
          ),
          ListTile(
            title: const Text('costa@example.com'),
            leading: Icon(Icons.contact_mail, color: Colors.blue[500]),
          ),
        ],
      ),
    ),
  );
}

ListTile

#

使用 ListTile,来自 Material 库 的一个专门的行小部件,可以轻松创建包含最多 3 行文本和可选的引导和尾随图标的行。ListTile 最常用于 CardListView 中,但也可以在其他地方使用。

摘要 (ListTile)

#
  • 一个包含最多 3 行文本和可选图标的专用行
  • 配置不如 Row 灵活,但更易于使用
  • 来自 Material 库

示例 (ListTile)

#
Card containing 3 ListTiles

一个包含 3 个 ListTileCard

应用源码: card_and_stack

4 ListTiles, each containing a leading avatar

使用带有引导小部件的 ListTile

Dart 代码: list_demo.dart


约束

#

要完全理解 Flutter 的布局系统,您需要了解 Flutter 如何定位和调整布局中的组件的大小。有关更多信息,请参阅 了解约束

视频

#

以下视频是 Flutter in Focus 系列的一部分,解释了 StatelessStateful 小部件。

在新的标签页上在 YouTube 上观看:“如何创建无状态小部件”

在新的标签页上在 YouTube 上观看:“何时以及如何最好地使用有状态小部件”

Flutter in Focus 播放列表


Widget of the Week 系列》的每个剧集都专注于一个小部件。其中一些包括布局小部件。

在新的标签页上在 YouTube 上观看:“介绍本周小部件”

Flutter Widget of the Week 播放列表

其他资源

#

以下资源可能在编写布局代码时有所帮助。

布局教程

学习如何构建布局。

组件目录

描述了 Flutter 中可用的许多小部件。

Flutter 中的 HTML/CSS 类比

对于熟悉 Web 编程的人员,此页面将 HTML/CSS 功能映射到 Flutter 功能。

API 参考文档

Flutter 所有库的参考文档。

添加资源和图像

解释了如何将图像和其他资源添加到应用程序的包中。

Flutter 从零到一

一个人编写他们的第一个 Flutter 应用程序的经验。