要開始使用 Flutter,你需要對 Dart 程式語言(Flutter 應用程式是用它編寫的)和 widgets(Flutter UI 的構建塊)有所瞭解。本頁將介紹這兩者,但你將在本系列的整個過程中繼續學習它們。本頁提供了額外的資源,但你不需要成為這兩個主題的專家即可繼續學習。

元件

#

關於 Flutter,你經常會聽到“一切皆 widget”。Widgets 是 Flutter 應用程式使用者介面的構建塊,每個 widget 都是使用者介面一部分的不可變宣告。Widgets 用於描述使用者介面的所有方面,包括文字和按鈕等物理方面,以及填充和對齊等佈局效果。

Widgets 基於組合形成一個層次結構。每個 widget 都巢狀在其父級中,並可以從父級接收上下文。這個結構一直延伸到根 widget,如下面的簡單示例所示:

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

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp( // Root widget
      home: Scaffold(
        appBar: AppBar(
          title: const Text('My Home Page'),
        ),
        body: Center(
          child: Builder(
            builder: (context) {
              return Column(
                children: [
                  const Text('Hello, World!'),
                  const SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () {
                      print('Click!');
                    },
                    child: const Text('A button'),
                  ),
                ],
              );
            },
          ),
        ),
      ),
    );
  }
}

在前面的程式碼中,所有例項化類都是 widgets:MaterialAppScaffoldAppBarTextCenterBuilderColumnSizedBoxElevatedButton

Widget 的組合

#

如前所述,Flutter 強調 widget 作為組合單元。Widgets 通常由許多其他小型的、單一用途的 widgets 組成,這些 widgets 結合起來可以產生強大的效果。

有佈局 widgets,如 PaddingAlignmentRowColumnGrid。這些佈局 widgets 沒有自己的視覺表示。相反,它們唯一的目的是控制另一個 widget 佈局的某些方面。Flutter 還包括利用這種組合方法的實用 widgets。例如,Container 是一個常用的 widget,它由多個負責佈局、繪製、定位和大小調整的 widgets 組成。一些 widgets 具有視覺表示,如前面示例中的 ElevatedButtonText,以及 IconImage 等 widgets。

如果你執行前面示例中的程式碼,Flutter 會繪製一個按鈕,上面寫著“Hello, World!”,居中顯示在螢幕上,垂直佈局。為了定位這些元素,有一個 Center widget,它將其子級定位在可用空間的中心,以及一個 Column widget,它將其子級一個接一個地垂直佈局。

A diagram that shows widget composition with a series of lines and nodes.

在本系列的下一頁中,你將學習更多關於 Flutter 中的佈局。

構建 widgets

#

要在 Flutter 中建立使用者介面,你需要覆蓋 widget 物件上的 build 方法。所有 widget 都必須有一個 build 方法,並且它必須返回另一個 widget。例如,如果你想在螢幕上新增一些帶有填充的文字,你可以這樣編寫:

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

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: const Text('Hello, World!'),
    );
  }
}

當這個 widget 建立時以及當這個 widget 的依賴項發生變化時(例如傳遞給 widget 的狀態),框架會呼叫 build 方法。這個方法可能會在每一幀中呼叫,並且除了構建 widget 之外不應該有任何副作用。要了解更多關於 Flutter 如何渲染 widgets 的資訊,請檢視 Flutter 架構概述

Widget 狀態

#

框架引入了兩大類 widget:無狀態和有狀態 widgets。

沒有可變狀態(它們沒有隨時間變化的類屬性)的 widgets 繼承自 StatelessWidget。許多內建 widgets 都是無狀態的,例如 PaddingTextIcon。當你建立自己的 widgets 時,大部分時間都會建立 Stateless widgets。

另一方面,如果 widget 的獨特特性需要根據使用者互動或其他因素而改變,那麼該 widget 就是有狀態的。例如,如果一個 widget 有一個計數器,每當使用者點選一個按鈕時它就會遞增,那麼計數器的值就是該 widget 的狀態。當該值改變時,widget 需要重新構建以更新其 UI 的一部分。這些 widgets 繼承自 StatefulWidget,並且(因為 widget 本身是不可變的)它們將可變狀態儲存在一個單獨的類中,該類繼承自 StateStatefulWidgets 沒有 build 方法;相反,它們的 UI 是透過它們的 State 物件構建的,如下面的示例所示。

dart
class CounterWidget extends StatefulWidget {
  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Text('$_counter');
  }
}

無論何時你修改 State 物件(例如,透過遞增計數器),你都必須呼叫 setState 來通知框架透過再次呼叫 Statebuild 方法來更新使用者介面。

將狀態與 widget 物件分離,可以讓其他 widgets 以完全相同的方式處理無狀態和有狀態 widgets,而無需擔心狀態丟失。父級無需為了保留子級狀態而持有子級,而是可以隨時建立子級的新例項而不會丟失子級的持久狀態。框架會在適當的時候完成查詢和重用現有狀態物件的所有工作。

本系列稍後將在狀態管理課程中提供有關 StatefulWidget 物件的更多資訊。

需要了解的重要 widgets

#

Flutter SDK 包含許多內建 widgets,從最小的 UI 片段(如 Text)到佈局 widgets,以及為你的應用程式設定樣式的 widgets。以下 widgets 是你在進入學習路徑的下一課時需要了解的最重要的 widgets。

Widget 預覽器

#

你可以即時檢視你的 widgets 渲染,而無需完整的應用程式。要了解更多資訊,請參閱 Flutter Widget 預覽器指南。

下一頁:佈局

#

本頁介紹了 Flutter 的基礎概念,例如 widgets,並幫助你熟悉閱讀 Flutter 和 Dart 程式碼。如果你對遇到的所有主題都不清楚也沒關係,因為在此之後的每一頁都會深入探討特定主題。在下一節中,你將透過在 Flutter 中建立更復雜的佈局來開始構建更有趣的使用者介面。

如果你想練習本頁學到的資訊,可以閱讀 使用 Flutter 構建使用者介面

反饋

#

由於網站的這一部分正在不斷發展,我們歡迎你的反饋