Widgets
若要開始使用 Flutter,您需要熟悉 Dart 程式語言,Flutter 應用程式就是以這種語言編寫的,以及 Widget,Widget 是 Flutter UI 的基礎建構區塊。此頁面將介紹這兩者,但您將在此系列中繼續學習它們。此頁面中列出了其他資源,但您不必成為這兩個主題的專家即可繼續。
Widgets
#關於 Flutter,您經常會聽到「一切皆為 Widget」。Widget 是 Flutter 應用程式使用者介面的建構區塊,每個 Widget 都是使用者介面一部分的不可變宣告。Widget 用於描述使用者介面的所有方面,包括文字和按鈕等實體方面,以及邊距和對齊方式等配置效果。
Widget 基於組成形成一個層次結構。每個 Widget 巢狀於其父 Widget 內,並可以接收來自父 Widget 的上下文。此結構一直延伸到根 Widget,如此簡單的範例所示
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'),
),
],
);
},
),
),
),
);
}
}
在上述程式碼中,所有實例化的類別都是 Widget:MaterialApp
、Scaffold
、AppBar
、Text
、Center
、Builder
、Column
、SizedBox
和 ElevatedButton
。
Widget 組成
#如前所述,Flutter 強調 Widget 作為組成的單位。Widget 通常由許多其他小型、單一用途的 Widget 組成,這些 Widget 結合起來可以產生強大的效果。
有版面配置 Widget,例如 Padding
、Alignment
、Row
、Column
和 Grid
。這些版面配置 Widget 本身沒有視覺表示。相反地,它們的唯一目的是控制另一個 Widget 版面配置的某些方面。Flutter 還包括利用此組成方法的實用 Widget。例如,Container
是一個常用的 Widget,它由多個負責版面配置、繪製、定位和調整大小的 Widget 組成。有些 Widget 具有視覺表示,例如前面範例中的 ElevatedButton
和 Text
,以及 Icon
和 Image
之類的 Widget。
如果您執行前面範例中的程式碼,Flutter 會繪製一個帶有文字「Hello, World!」的按鈕,該按鈕位於螢幕中央,並垂直配置。若要定位這些元素,會有一個 Center
Widget,它將其子項定位在可用空間的中央,以及一個 Column
Widget,它將其子項一個接一個地垂直配置。
在本系列的下一頁中,您將深入了解 Flutter 中的版面配置。
建立 Widget
#若要在 Flutter 中建立使用者介面,您需要覆寫 Widget 物件上的 build
方法。所有 Widget 都必須具有 build 方法,而且必須傳回另一個 Widget。例如,如果您想在螢幕上新增帶有一些邊距的文字,您可以這樣寫
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 如何呈現 Widget,請查看Flutter 架構概述。
Widget 狀態
#框架引入了兩個主要類別的 Widget:有狀態和無狀態 Widget。
沒有可變狀態的 Widget(它們沒有隨時間變更的類別屬性)會繼承 StatelessWidget
。許多內建 Widget 都是無狀態的,例如 Padding
、Text
和 Icon
。當您建立自己的 Widget 時,您大部分時間都會建立 Stateless
Widget。
另一方面,如果 Widget 的獨特特性需要根據使用者互動或其他因素而變更,則該 Widget 就是有狀態的。例如,如果 Widget 有一個計數器,每當使用者點擊按鈕時,計數器就會遞增,那麼計數器的值就是該 Widget 的狀態。當該值變更時,需要重新建立 Widget,以更新其 UI 的一部分。這些 Widget 會繼承 StatefulWidget
,並且(因為 Widget 本身是不可變的)它們會將可變狀態儲存在繼承 State
的單獨類別中。StatefulWidgets
沒有 build
方法;相反地,它們的使用者介面是透過它們的 State
物件建立的,如下例所示。
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
來發出訊號,通知框架透過再次呼叫 State
的 build
方法來更新使用者介面。
將狀態與 Widget 物件分離,可讓其他 Widget 以完全相同的方式處理無狀態和有狀態 Widget,而無需擔心狀態遺失。父項可以隨時建立子項的新執行個體,而不會遺失子項的持續狀態,而不需要保留子項來保留其狀態。框架會在適當時執行尋找和重複使用現有狀態物件的所有工作。
本系列稍後會提供更多關於 StatefulWidget
物件的資訊,請參閱狀態管理課程。
需要了解的重要 Widget
#Flutter SDK 包含許多內建 Widget,從最小的 UI 片段(例如 Text
)到版面配置 Widget,以及設定應用程式樣式的 Widget。在您進入學習路徑中的下一課時,請務必注意以下 Widget。
下一步:版面配置
#此頁面簡介了 Flutter 的基礎概念,例如 Widget,並可協助您熟悉閱讀 Flutter 和 Dart 程式碼。如果您對遇到的每個主題都不是很清楚,也沒關係,因為之後的每個頁面都會深入探討特定主題。在下一節中,您將開始透過在 Flutter 中建立更複雜的版面配置來建立更有趣的 UI。
如果您想練習在此頁面中學到的資訊,您可以閱讀使用 Flutter 建立使用者介面。
意見回饋
#由於網站的此部分仍在發展中,我們歡迎您提供意見回饋!
除非另有說明,否則本網站上的文件會反映 Flutter 的最新穩定版本。頁面上次更新時間為 2024-10-23。 檢視原始碼 或回報問題。