Skip to main content

Flutter 布局

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

通过组合 Widget 来构建更复杂的 Widget,从而创建布局。 例如,下面的第一个屏幕截图显示了 3 个图标,每个图标下面都有一个标签:

示例布局 带有可视化调试的示例布局

第二个屏幕截图显示了可视化布局,显示了 3 列的行,其中每一列包含一个图标和一个标签。

这是此 UI 的 Widget 树的图表:

节点树

大部分内容看起来都符合预期,但您可能想知道容器(以粉色显示)。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,它将其内容水平和垂直居中。

2. 创建可见 Widget

#

例如,创建一个 Text Widget:

dart
Text('Hello World'),

创建一个 Image Widget:

dart
return Image.asset(
  image,
  fit: BoxFit.cover,
);

创建一个 Icon Widget:

dart
Icon(
  Icons.star,
  color: Colors.red[500],
),

3. 将可见 Widget 添加到布局 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。

Material 应用

#

对于 Material 应用,您可以使用 Scaffold Widget;它提供默认横幅、背景颜色,并具有用于添加抽屉、Snack bar 和底部表单的 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 应用

#

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

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

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

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

  • 要布局应用的主体,请使用所需的 Widget 作为其值设置脚手架的 child 属性,例如 CenterColumn

要了解您可以添加哪些其他 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: <Widget>[
              Text('Hello World'),
            ],
          ),
        ),
      ),
    );
  }
}

非 Material 应用

#

对于非 Material 应用,您可以将 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,
          ),
        ),
      ),
    );
  }
}

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

就是这样!运行应用时,您应该会看到 Hello World

应用源代码:

Hello World

垂直和水平布局多个 Widget

#

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

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

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

带有标注的屏幕截图,显示包含两个子项的行

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

显示分解为子行和子列的左侧列的图表

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

对齐 Widget

#

您可以使用 mainAxisAlignmentcrossAxisAlignment 属性来控制行或列如何对齐其子项。对于行,主轴沿水平方向运行,交叉轴沿垂直方向运行。对于列,主轴沿垂直方向运行,交叉轴沿水平方向运行。

显示行的主轴和交叉轴的图表 显示列的主轴和交叉轴的图表

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

在下面的示例中,每张 3 张图像的宽度均为 100 像素。渲染框(在本例中为整个屏幕)的宽度超过 300 像素,因此将主轴对齐方式设置为 spaceEvenly 会将自由水平空间平均分配到每个图像之间、之前和之后。

dart
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Image.asset('images/pic1.jpg'),
    Image.asset('images/pic2.jpg'),
    Image.asset('images/pic3.jpg'),
  ],
);
具有 3 个均匀间隔图像的行

应用源代码: 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'),
  ],
);

应用源代码: row_column

显示 3 个均匀间隔图像的列

Widget 大小调整

#

当布局过大而无法容纳在设备中时,会在受影响的边缘显示黄色和黑色条纹图案。这是一个显示过宽行的示例

过宽的行

可以使用 Expanded Widget 将 Widget 大小调整为适合行或列。要修复前面图像行过宽而无法容纳在其渲染框中的示例,请将每个图像用 Expanded Widget 包装起来。

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'),
    ),
  ],
);
3 个图像的行,它们太宽了,但每个图像都被限制为只占用 1/3 的空间

应用源代码: sizing

也许您希望 Widget 占据与其同级 Widget 两倍的空间。为此,请使用 Expanded Widget 的 flex 属性,这是一个确定 Widget 伸缩因子的整数。默认伸缩因子为 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'),
    ),
  ],
);
3 个图像的行,中间图像的宽度是其他图像的两倍

应用源代码: 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),
  ],
)
5 个星形图标的行,紧凑地排列在行的中间

应用源代码: pavlova

嵌套行和列

#

布局框架允许您根据需要在行和列中嵌套行和列。让我们来看一下以下布局概述部分的代码:

Pavlova 应用的屏幕截图,其中评分和图标行用红色概述

概述部分实现为两行。评分行包含五个星形图标和评论数量。图标行包含三列图标和文本。

评分行的 Widget 树:

评分行 Widget 树

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 列;每一列都包含一个图标和两行文本,正如您在其 Widget 树中看到的那样:

<img src='/assets/images/docs/ui/layout/widget-tree-pavlova-icon-row.png' class="mw-100 text-center' alt="图标 Widget 树">

iconList 变量定义了图标行:

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

// DefaultTextStyle.merge() 允许您创建一个默认文本样式,该样式由其子项和所有后续子项继承。
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 有一个丰富的布局 Widget 库。以下是一些最常用的 Widget。目的是让您尽快开始运行,而不是让您被完整的列表淹没。有关其他可用 Widget 的信息,请参阅Widget 目录,或使用API 参考文档中的搜索框。此外,API 文档中的 Widget 页面通常会建议可能更适合您需求的类似 Widget。

以下 Widget 分为两类:Widget 库中的标准 Widget 和Material 库中的专用 Widget。任何应用都可以使用 Widget 库,但只有 Material 应用才能使用 Material 组件库。

标准 Widget

#
  • Container:向 Widget 添加填充、边距、边框、背景颜色或其他装饰。
  • GridView:将 Widget 布局为可滚动的网格。
  • ListView:将 Widget 布局为可滚动的列表。
  • Stack:将一个 Widget 重叠在另一个 Widget 上。

Material Widget

#
  • Card:将相关信息组织到具有圆角和投影的框中。
  • ListTile:将最多 3 行文本以及可选的前导和尾随图标组织成一行。

Container

#

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

摘要 (Container)

  • 添加填充、边距、边框
  • 更改背景颜色或图像
  • 包含单个子 Widget,但该子 Widget 可以是 Row、Column,甚至是 Widget 树的根
图表显示:边距、边框、填充和内容

示例 (Container)

#

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

dart
Widget _buildImageColumn() {
  return Container(
    decoration: const BoxDecoration(
      color: Colors.black26,
    ),
    child: Column(
      children: [
        _buildImageRow(1),
        _buildImageRow(3),
      ],
    ),
  );
}
屏幕截图显示 2 行,每行包含 2 个图像

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 将 Widget 布局为二维列表。GridView 提供两个预制列表,或者您可以构建您自己的自定义网格。当 GridView 检测到其内容过长而无法容纳在渲染框中时,它会自动滚动。

摘要 (GridView)

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

示例 (GridView)

#
照片的 3 列网格

使用 GridView.extent 创建一个网格,其图块最大宽度为 150 像素。

应用源代码: grid_and_list

具有页脚的 2 列网格

使用 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));

// 图像以 pic0.jpg、pic1.jpg...pic29.jpg 的名称保存。
// List.generate() 构造函数允许在对象具有可预测的命名模式时轻松创建列表。
List<Widget> _buildGridTileList(int count) =>
    List.generate(count, (i) => Image.asset('images/pic$i.jpg'));

ListView

#

ListView 是一种类似列的 Widget,当其内容过长而无法容纳在其渲染框中时,会自动提供滚动。

摘要 (ListView)

#
  • 用于组织框列表的专用 Column
  • 可以水平或垂直布局
  • 检测其内容何时无法容纳并提供滚动
  • Column 的配置较少,但更易于使用并支持滚动

示例 (ListView)

#
包含电影院和餐馆的 ListView

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

应用源代码: grid_and_list

包含蓝色色调的 ListView

使用 ListView 显示Material 2 设计调色板 中特定颜色系列的 Colors

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 将 Widget 排列在基本 Widget(通常是图像)的顶部。Widget 可以完全或部分重叠基本 Widget。

摘要 (Stack)

#
  • 用于重叠另一个 Widget 的 Widget
  • 子 Widget 列表中的第一个 Widget 是基本 Widget;后续子 Widget 重叠在该基本 Widget 的顶部
  • Stack 的内容无法滚动
  • 您可以选择裁剪超过渲染框的子 Widget

示例 (Stack)

#
带有标签的圆形头像图像

使用 StackContainer(在其半透明黑色背景上显示其 Text)叠加在 CircleAvatar 的顶部。Stack 使用 alignment 属性和 Alignment 来偏移文本。

应用源代码: card_and_stack

图像上叠加的图标

使用 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 库,包含相关信息片段,并且可以

几乎可以由任何 Widget 组成,但通常与 ListTile 一起使用。Card 只有一个子 Widget,但其子 Widget 可以是列、行、列表、网格或其他支持多个子 Widget 的 Widget。默认情况下,Card 将其大小缩小到 0 x 0 像素。您可以使用 SizedBox 来约束卡片的大小。

在 Flutter 中,Card 具有略微圆角和投影,使其具有 3D 效果。更改 Cardelevation 属性可以控制投影效果。例如,将 elevation 设置为 24 会使 Card 从表面进一步抬起,并导致阴影变得更加分散。有关支持的 elevation 值列表,请参阅Material 指南中的Elevation。指定不支持的值会完全禁用投影。

摘要 (Card)

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

示例 (Card)

#
包含 3 个 ListTile 的 Card

一个包含 3 个 ListTile 的 Card,其大小通过用 SizedBox 包装来确定。Divider 将第一个和第二个 ListTile 分隔开。

应用源代码: card_and_stack

包含图像和多种文本形式的可点击卡片

一个包含图像和文本的 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('[email protected]'),
            leading: Icon(
              Icons.contact_mail,
              color: Colors.blue[500],
            ),
          ),
        ],
      ),
    ),
  );
}

ListTile

#

使用 ListTile,这是 Material 库 中一个专用的行 Widget,可以轻松创建包含最多 3 行文本以及可选的前导和尾随图标的行。ListTile 最常用于 CardListView,但也可以用在其他地方。

摘要 (ListTile)

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

示例 (ListTile)

#
包含 3 个 ListTile 的 Card

一个包含 3 个 ListTile 的 Card。

应用源代码: card_and_stack

4 个 ListTile,每个都包含一个前导头像

使用带有前导 Widget 的 ListTile

Dart 代码: list_demo.dart


约束

#

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

视频

#

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



Flutter in Focus 播放列表


每周 Widget 系列的每一集都重点介绍一个 Widget。其中一些包含布局 Widget。


Flutter 每周 Widget 播放列表

其他资源

#

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

布局教程
了解如何构建布局。
Widget 目录
描述 Flutter 中提供的许多 Widget。
Flutter 中的 HTML/CSS 等效项
对于熟悉 Web 编程的人员,此页面将 HTML/CSS 功能映射到 Flutter 功能。
API 参考文档
所有 Flutter 库的参考文档。
添加资源和图像
解释如何将图像和其他资源添加到应用的包中。
Flutter 从零到一
一位个人编写他的第一个 Flutter 应用的经验。