Kodokon kodokon.com

布局:Row、Column、Padding、Expanded、SizedBox

使用列、行、间距和空间分配,把多个 widget 组织到屏幕上。

9 分钟 · 3 题

在 Kodokon 中打开本课

一个真实的屏幕很少只显示单个 widget:你需要把它们组织起来。这正是布局 widget 的工作。Column 把它的子节点垂直地从上到下堆叠;Row 则把它们水平地从左到右排列。由于它们接受多个子节点,参数就不再叫 child 而是 children,并且它接收一个列表:写在方括号 [ ] 之间、用逗号隔开的一组 widget。

DART
import 'package:flutter/material.dart';

Widget buildProfile() {
  return const Column(
    children: [
      Icon(Icons.person, size: 48),
      Text("Sonia Ben Ali"),
      Text("Flutter Developer"),
    ],
  );
}
一个 Column 把它的子节点从上到下堆叠

Row 的工作方式完全相同,只不过是水平方向的。它的主轴是宽度:mainAxisAlignment 参数决定如何沿着这条轴分配子节点(center 把它们聚拢到中间,spaceBetween 把它们尽可能地分散开……)。而要在两个 widget 之间塞进一处简单的空白,就用 SizedBox:一个隐形的盒子,它的宽度(width)或高度(height)由你设定。

DART
import 'package:flutter/material.dart';

Widget buildRating() {
  return const Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Icon(Icons.star, color: Colors.amber),
      SizedBox(width: 8),
      Text("4.8 out of 5"),
    ],
  );
}
一个居中的 Row,图标和文本之间隔着 8 像素

Padding 在它的子节点四周添加空白,这样内容就不会贴着边缘。空白的大小用 EdgeInsets 来描述:EdgeInsets.all(16) 在四条边上各放 16 像素,EdgeInsets.only(left: 8) 只在左边放,而 EdgeInsets.symmetric(horizontal: 12) 则同时在左右两边放。

DART
import 'package:flutter/material.dart';

Widget buildQuote() {
  return const Padding(
    padding: EdgeInsets.all(16),
    child: Text("A text with some room around it"),
  );
}
文本四周各 16 像素的空白

最后一个工具:Expanded。把它放在 RowColumn 的子节点之中,它会要求自己的子节点占据所有剩余空间。在下面的例子中,灰色盒子保持它 80 像素的宽度,而青色盒子则会伸展开来,填满宽度的其余部分,无论屏幕多大。

DART
import 'package:flutter/material.dart';

Widget buildProgress() {
  return Row(
    children: [
      Container(width: 80, height: 40, color: Colors.grey),
      Expanded(
        child: Container(height: 40, color: Colors.teal),
      ),
    ],
  );
}
Expanded 把它的子节点伸展到占满所有剩余空间

知识检测

确认你已牢记本课的重点内容。

  1. Column 会朝哪个方向排列它的子节点?
    • 水平方向,从左到右
    • 垂直方向,从上到下
    • 环形,围绕屏幕中心
  2. Expanded widget 有什么用?
    • 让它的子节点占据 Row 或 Column 中所有剩余空间
    • 放大屏幕上每一段文本的字体
    • 在你触摸时放大一张图片
  3. 如何在一个 Row 里的两个 widget 之间插入一处 8 像素的空白?
    • 在两者之间放一个 SizedBox(width: 8)
    • 按八次空格键
    • 用一个 Expanded(width: 8)