跳到主內容

Flutter 中的佈局

瞭解 Flutter 的佈局機制以及如何構建應用的佈局。

概述

#

Flutter 佈局機制的核心是 Widget。在 Flutter 中,幾乎一切都是 Widget——甚至是佈局模型本身也是 Widget。你在 Flutter 應用中看到的影像、圖示和文字都是 Widget。但那些你看不到的東西也是 Widget,例如用於排列、約束和對齊可見 Widget 的行(Row)、列(Column)和網格(Grid)。你透過組合 Widget 來構建更復雜的 Widget,從而建立佈局。

概念示例

#

在下面的示例中,第一張截圖顯示了三個帶有標籤的圖示,第二張截圖顯示了行和列的視覺佈局。在第二張截圖中,debugPaintSizeEnabled 被設定為 true,以便你可以看到視覺佈局。

Sample layout
Sample layout with visual debugging

這是上述示例的 Widget 樹圖示

Node tree

大部分內容應該如你所料,但你可能對其中的容器(以粉色顯示)感到好奇。Container 是一個 Widget 類,允許你自定義其子 Widget。當你想要新增內邊距、外邊距、邊框或背景顏色時,可以使用 Container,這些只是它功能的一部分。

每個 Text Widget 都被放置在一個 Container 中以新增外邊距。整個 Row 也被放置在一個 Container 中,以在行周圍新增內邊距。

其餘 UI 由屬性控制。使用 Iconcolor 屬性設定其顏色。使用 Text.style 屬性來設定字型、顏色、字重等。列(Column)和行(Row)擁有屬性,允許你指定其子項如何進行垂直或水平對齊,以及子項應占用多少空間。

佈局一個 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;它提供了預設橫幅、背景顏色,並擁有用於新增抽屜(drawer)、小吃欄(snack bar)和底部工作表(bottom sheet)的 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 新增到 scaffold 的 navigationBar 屬性中。你可以使用 CupertinoColors 提供的顏色來配置你的 Widget,以匹配 iOS 設計。

  • 要佈局應用的主體,請將 scaffold 的 child 屬性設定為所需的 Widget,例如 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: [Text('Hello World')],
          ),
        ),
      ),
    );
  }
}

5. 執行你的應用

#

新增完 Widget 後,執行你的應用。當你執行應用時,你應該能看到 Hello World

應用原始碼

Screenshot of app displaying Hello World

最常見的佈局模式之一是垂直或水平排列 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

你將在 巢狀 Row 和 Column 中實現 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 列舉提供了多種用於控制對齊的常量。

在以下示例中,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'),
  ],
);
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 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')),
  ],
);
Row of 3 images that are too wide, but each is constrained to take only 1/3 of the space

應用原始碼: sizing

也許你希望一個 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')),
  ],
);
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

巢狀 Row 和 Column

#

佈局框架允許你根據需要深度巢狀行和列。讓我們看看以下佈局中突出顯示部分的相應程式碼: Screenshot of the pavlova app, with the ratings and icon rows outlined in red

突出顯示的部分實現為兩行。評分行包含五顆星和評論數量。圖示行包含三列圖示和文字。

評分行的 Widget 樹: 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 列;每一列都包含一個圖示和兩行文字,正如你在其 Widget 樹中看到的那樣: 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 擁有豐富的佈局 Widget 庫。以下是一些最常用的 Widget。我們的目的是讓你儘快上手,而不是用完整的列表淹沒你。有關其他可用 Widget 的資訊,請參閱 Widget 目錄,或在 API 參考文件 中使用搜索框。此外,API 文件中的 Widget 頁面通常會建議可能更適合你需求的其他類似 Widget。

以下 Widget 分為兩類:widgets 庫 中的標準 Widget,以及 Material 庫 中的專用 Widget。任何應用都可以使用 widgets 庫,但只有 Material 應用可以使用 Material 元件庫。

容器

為 Widget 新增內邊距、外邊距、邊框、背景顏色或其他裝飾。

GridView

將 Widget 佈局為可滾動的網格。

ListView

將 Widget 佈局為可滾動的列表。

層疊佈局

將一個 Widget 重疊在另一個 Widget 之上。

Scaffold

提供了一個結構化的佈局框架,併為常見的 Material Design 應用元素留出了位置。

AppBar

建立一個通常顯示在螢幕頂部的水平條。

Card

將相關資訊組織在具有圓角和陰影的盒子中。

ListTile

將最多 3 行文字以及可選的前導和尾隨圖示組織成一行。

CupertinoPageScaffold

為 iOS 風格的頁面提供基本佈局結構。

CupertinoNavigationBar

在螢幕頂部建立 iOS 風格的導航欄。

CupertinoSegmentedControl

建立用於選擇的分段控制元件。

CupertinoTabBarCupertinoTabScaffold

建立典型的 iOS 底部標籤欄。

容器

#

許多佈局都會大量使用 Container 來透過內邊距分隔 Widget,或新增邊框和外邊距。你可以透過將整個佈局放入 Container 並更改其背景顏色或影像來更改裝置的背景。

總結 (Container)#

  • 新增內邊距、外邊距、邊框
  • 更改背景顏色或影像
  • 包含單個子 Widget,但該子項可以是 RowColumn 甚至是 Widget 樹的根節點。
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 將 Widget 佈局為二維列表。GridView 提供了兩個預製列表,或者你可以構建自己的自定義網格。當 GridView 檢測到其內容太長而無法適應渲染框時,它會自動滾動。

總結 (GridView) #

  • 以網格形式佈局 Widget
  • 檢測列內容何時超過渲染框並自動提供滾動
  • 構建你自己的自定義網格,或使用提供的網格之一
  • GridView.count 允許你指定列數
  • GridView.extent 允許你指定瓦片(tile)的最大畫素寬度

示例 (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 是一種類似列的 Widget,當內容對於其渲染框來說太長時,它會自動提供滾動功能。

總結 (ListView) #

  • 一種用於組織盒子列表的專用 Column
  • 可以水平或垂直佈局
  • 檢測內容何時無法容納並提供滾動
  • Column 配置選項少,但更易於使用且支援滾動

示例 (ListView) #

ListView containing movie theaters and restaurants

使用 ListView 透過 ListTile 顯示企業列表。Divider 用於將劇院與餐館分開。

應用原始碼: grid_and_list

ListView containing shades of blue

使用 ListView 顯示特定顏色系列的 Colors(來自 Material 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 在基礎 Widget(通常是影像)之上排列 Widget。這些 Widget 可以完全或部分重疊基礎 Widget。

總結 (Stack) #

  • 用於與其他 Widget 重疊的 Widget
  • 子項列表中的第一個 Widget 是基礎 Widget;後續子項將覆蓋在該基礎 Widget 之上
  • Stack 的內容無法滾動
  • 你可以選擇剪裁超出渲染框的子項

示例 (Stack) #

Circular avatar image with a label

使用 StackContainer(在半透明黑色背景上顯示其 Text)覆蓋在 CircleAvatar 之上。Stack 使用 alignment 屬性和 Alignments 來偏移文字。

應用原始碼: 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

#

來自 Material 庫Card 包含相關的資訊片段,幾乎可以由任何 Widget 組成,但通常與 ListTile 一起使用。Card 只有一個子項,但該子項可以是列、行、列表、網格或其他支援多個子項的 Widget。預設情況下,Card 會將其大小縮小到 0x0 畫素。你可以使用 SizedBox 來約束卡片的大小。

在 Flutter 中,Card 具有略微圓角和投影,使其具有 3D 效果。更改 Cardelevation 屬性允許你控制投影效果。例如,將高程(elevation)設定為 24,視覺上會將 Card 從表面進一步提升,並使陰影變得更加分散。有關支援的高程值列表,請參閱 Material 指南 中的 Elevation。指定不支援的值會完全停用投影。

總結 (Card) #

  • 實現 Material 卡片
  • 用於呈現相關的資訊片段
  • 接受單個子項,但該子項可以是 RowColumn 或其他包含子項列表的 Widget
  • 以圓角和投影顯示
  • Card 的內容無法滾動
  • 來自 Material 庫

示例 (Card) #

Card containing 3 ListTiles

一個包含 3 個 ListTile 的 Card,並透過使用 SizedBox 包裝來調整大小。Divider 將第一個和第二個 ListTile 分隔開。

應用原始碼: 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 庫 的專用行 Widget)可以輕鬆建立一個包含最多 3 行文字以及可選前導和尾隨圖示的行。ListTile 最常用於 CardListView 中,但也可用於其他地方。

總結 (ListTile) #

  • 一種專用行,包含最多 3 行文字和可選圖示
  • Row 配置選項少,但更易於使用
  • 來自 Material 庫

示例 (ListTile) #

Card containing 3 ListTiles

一個包含 3 個 ListTileCard

應用原始碼: card_and_stack

4 ListTiles, each containing a leading avatar

使用帶有前導 Widget 的 ListTile

Dart 程式碼: list_demo.dart


約束

#

要完全理解 Flutter 的佈局系統,你需要了解 Flutter 如何在佈局中定位和調整元件的大小。有關更多資訊,請參閱 理解約束

影片

#

以下影片是 Flutter in Focus 系列的一部分,解釋了 StatelessStateful Widget。

在 YouTube 新標籤頁中觀看:“如何建立無狀態 Widget”

在 YouTube 新標籤頁中觀看:“如何以及何時最好地使用有狀態 Widget”

Flutter in Focus 播放列表


Widget of the Week 系列 的每一集都專注於一個 Widget。其中幾個集數包含了佈局 Widget。

在 YouTube 新標籤頁中觀看:“Widget of the Week 介紹”

Flutter Widget of the Week 播放列表

以下資源在編寫佈局程式碼時可能會有所幫助。

佈局教程

學習如何構建佈局。

元件目錄

描述了 Flutter 中可用的許多 Widget。

Flutter 中的 HTML/CSS 對應物

對於熟悉 Web 程式設計的人來說,此頁面將 HTML/CSS 功能對映到 Flutter 功能。

API 參考文件

所有 Flutter 庫的參考文件。

新增資源和影像

解釋如何嚮應用包中新增影像和其他資源。

從零到一使用 Flutter

一個人編寫其第一個 Flutter 應用的經驗。