Flutter 是什麼?
我們先來搬運官網的一段介紹,讓大家有一個直觀的認識:
Flutter是谷歌的移動UI框架,可以快速在 iOS 和 Android 上構建高質量的原生使用者介面。
Flutter可以與現有的程式碼一起工作。在全世界,Flutter正在被越來越多的開發者和組織使用,並且Flutter是完全免費、開源的。
複製程式碼
簡而言之
- 跨端(移動、Web、桌⾯、嵌⼊式)
- ⾼效能(Dart)
- ⾼效開發(熱過載)
- 富有表現⼒的 UI(Widget)
溫馨提示
- 搭建開發環境
- Dart簡介
- ......
這些我們都不講,今天我們聊一下 Flutter Widget 。讓我們開始吧~
Widget 簡介
概念
Widget 描述了在當前的配置和狀態下,檢視所應該 呈現的樣⼦。當 Widget 的狀態改變時,它會重新構 建其描述(展示的 UI),框架則會對⽐前後變化的 不同,以確定底層渲染樹從⼀個狀態轉換到下⼀個狀 態所需的最⼩更改。
Widget目錄
描述元素的配置
示例-1
示例-2
Widget 結構
Widget 組合的結構是樹,所以叫Widget 樹。樹中包含
根Widget
- WidgetsApp【自定義風格】
- MaterialApp【基於 WidgetsApp的Material Design 風格
(常用)
】 - CupertinoApp【基於 WidgetsApp 實現的 iOS 風格】
父Widget
子Widget
// main.dart
import 'package:flutter/material.dart'; //風格需要先匯入哦~
import 'my_home_page_widget.dart';
void main() => runApp(MyApp()); //Flutter會預設把 根Widget 充滿螢幕
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.light(),
home: MyHomePage(title: 'Vava熊の日記'),
);
}
}
複製程式碼
Widget 與 Element
- Widget樹實際上是一個配置樹,而真正的UI渲染樹是由Element構成。
- 一個Widget物件可以對應多個Element物件。根據同一份配置(Widget),可以建立多個例項(Element)。
graph LR
Widget配置--> Element1
Widget配置--> Element2
Widget配置--> Element3
Widget配置--> ...
複製程式碼
Widget 狀態分類
因為渲染是很耗效能的,為了提高 Flutter 的幀率,就要儘量減少不必要的 UI 渲染,所以 Flutter 根據 UI 是否有變化,將 Widget 分為StatelessWidget
&& StatefulWidget
。
StatelessWidget
和StatefulWidget
都是直接繼承自Widget類,它們引入了兩種Widget模型,接下來我們將重點介紹一下這兩個類。
StatelessWidget:immutable(狀態不可變)
StatelessWidget是不可變狀態的 Widget 抽象類, 只能在載入/構建 Widget 時才繪製一次,無法基於任何事件或使用者操作重繪。所以 StatelessWidget生命週期就只有一個
,即 build
函式。
StatelessWidget の Demo
// main.dart
import 'package:flutter/material.dart';
import 'stateless.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.light(),
home: MyStatelessApp("123 木頭人,不許動 ——from Vava熊")
);
}
}
複製程式碼
//stateless.dart
import 'package:flutter/material.dart';
class MyStatelessApp extends StatelessWidget {
final String content;
MyStatelessApp(this.content);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:AppBar(
title: Text('StatelessWidget'),
),
body:Center(
child: Text(content),
)
);
}
}
複製程式碼
效果圖
StatefulWidget 及 State
- 可變狀態的 Widget
- 建立 State 物件
- 多生命週期
StatefulWidget の Demo
每點選文字一次,body文字中就會多一次‘贊’
// main.dart
import 'package:flutter/material.dart';
import 'stateful.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.light(),
home: MyStatefulApp("Vava熊の一天")
);
}
}
複製程式碼
//stateful.dart
import 'package:flutter/material.dart';
class MyStatefulApp extends StatefulWidget {
String content;
MyStatefulApp(this.content);
@override
State<StatefulWidget> createState() {
return MyStatefulAppState();
}
}
class MyStatefulAppState extends State<MyStatefulApp> {
bool isShowText =true;
void increment(){
setState(() {
widget.content += "贊";
});
}
//build() 方法在 didChangeDependencies()(或者 didUpdateWidget() )之後呼叫
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:AppBar(
title: Text('StatefulWidget及State'),
),
body:Center(
child: GestureDetector(
child: isShowText? Text(widget.content) :null,
onTap: increment,
)
)
);
}
//-------only 生命週期 log------------
//建立 State 物件後要呼叫的第一個方法
@override
void initState() {
super.initState();
print("initState");
context.runtimeType;
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("didChangeDependencies");
}
//runtimeType 和 Widget.key 都一樣,那麼就會呼叫 didUpdateWidget()。
@override
void didUpdateWidget(MyStatefulApp oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget");
}
// StaefulWidget 從樹中移除時
@override
void dispose() {
super.dispose();
print("dispose");
}
//執行 HotReload,就會觸發 reassemble(),這提供了重新初始化在 initState() 方法中準備的任何資料的機會,包括全域性變數。
@override
void reassemble() {
super.reassemble();
print("reassemble");
}
}
複製程式碼
效果圖
State 的生命週期
在上面的例子中,除了效果外,我們也看到了關於生命週期的備註資訊。
// 控制檯日誌
// 1.第一次 | 新開啟
....
Restarted application in 1,153ms.
flutter: initState
flutter: didChangeDependencies
flutter: reassemble
flutter: didUpdateWidget
...
// 2.我們點選⚡️按鈕熱過載
...
Syncing files to device iPhone Xʀ...
flutter: reassemble
flutter: didUpdateWidget
...
// 3. 移除 widget
...
flutter: reassemble
flutter: dispose
Reloaded 2 of 442 libraries in 117ms.
...
複製程式碼
盜圖小結
葵花寶典:如果 UI 需要改變,就用 StatefulWidget。不需要改變,就用 StatelessWidget。
寫在最後の總結
Widget 特點
- 一切皆 Widget
- UI的配置資訊
- 一次性的
- 輕量的
Widget 應用
Widget 眾多,需要開發者們更多地實踐與效能的關注。 路漫漫其修遠兮,今天也要加油鴨~
關於我們
快狗叫車前端團隊專注前端技術分享,定期推送高質量文章,歡迎關注點贊。
文章同步釋出在公眾號喲,想要第一時間得到最新的資訊,just scan it !