
前言
說起 AppBar 組件,大家都比較熟悉,默認(rèn)情況下是一個(gè) Material 風(fēng)格的頭部標(biāo)題欄。可能有人疑惑,這么簡(jiǎn)單的東西,有什么好說的?其實(shí)該組件一些重要的屬性很多人都不知道,另外在使用過程中有一些細(xì)節(jié),本文將結(jié)合使用和源碼來詳細(xì)探討一下 AppBar 組件。
如下是 Material 2 和 Material 3 風(fēng)格下默認(rèn)的 AppBar 展示效果:Material 2 | Material 3 |
---|---|
![]() |
![]() |
AppBar(title: const Text('AppBar 組件')),
AppBar 組件的高度
對(duì)于 AppBar 來說,最重要的莫過于它的高度,那它的高度是如何確定的呢?這就不得不說 PreferredSizeWidget 一族的組件了。如下可見,它實(shí)現(xiàn)了 PreferredSizeWidget 類:

如下所示,PreferredSizeWidget是一個(gè)抽象類,其中定義了 preferredSize 抽象 get 方法,返回 Size 對(duì)象。也就是說該族的組件是需要預(yù)先設(shè)定尺寸的:
abstract class PreferredSizeWidget implements Widget {
Size get preferredSize;
}
所以 AppBar 既然實(shí)現(xiàn) PreferredSizeWidget,就必然實(shí)現(xiàn) preferredSize 方法,返回尺寸。所以根據(jù)這個(gè)線索可以知道高度是如何確定的: AppBar 中定義了preferredSize 成員,所以抽象的 get 方法,將獲取該成員:
在 AppBar 構(gòu)造方法中,preferredSize 被賦值為 _PreferredAppBarSize 對(duì)象,其中有兩個(gè)入?yún)? toolbarHeight,和 bottom 的高度。


---->[AppBar]----
final Size preferredSize;
---->[_PreferredAppBarSize]----
class _PreferredAppBarSize extends Size {
_PreferredAppBarSize(this.toolbarHeight, this.bottomHeight)
: super.fromHeight((toolbarHeight ?? kToolbarHeight) + (bottomHeight ?? 0));
final double? toolbarHeight;
final double? bottomHeight;
}
---->[Size#fromHeight]----
const Size.fromHeight(double height) : super(double.infinity, height);
另外 AppBar 是可以指定 PreferredSizeWidget 類型的 bottom 組件,在標(biāo)題的底部展示。如下所示,所以可以說,AppBar 組件的高度就是 toolbarHeight 和 bottom 組件高度之和。
---->[AppBar]----
final PreferredSizeWidget? bottom;
final double? toolbarHeight;
另外,可以通過參數(shù)指定 toolbarHeight 的值,如下是 40 的效果,可以看出標(biāo)題的高度變小,但并不會(huì)影響 bottom。

AppBar(
title: const Text('AppBar 組件'),
toolbarHeight: 40,
),
關(guān)于 AppBar 的高度需要注意的就是這些,一般來說 AppBar 作為 Scaffold#appBar 屬性的欽定組件使用,不會(huì)在外界單獨(dú)使用。
AppBar 組件的部位
一個(gè)普通的 AppBar可以包含如下四個(gè)部位,leading 是左側(cè)組件,title 是中間組件,actions 的右側(cè)組件列表。bottom 是底部組件:

---->[AppBar]----
final PreferredSizeWidget? bottom;
final Widget? leading;
final Widget? title;
final List? actions;
通過查看布局效果可以更清晰地看出 AppBar 各部位的占位情況,

另外,還有一個(gè) Widlget 類型的 flexibleSpace 屬性,在源碼實(shí)現(xiàn)的過程中,該組件將通過 Stack 疊放在 AppBar下方。效果如下,如果普通的 AppBar 底部用貼圖的需求,可以使用這個(gè)屬性:

[AppBar]----final Widget? flexibleSpace;
部位相關(guān)控制屬性
下面介紹一些關(guān)于部位的屬性: centerTitle 是一個(gè) bool 值,可以控制 title 是否居中顯示。這個(gè)是在整體的居中,所以 AppBar 的標(biāo)題欄并不是一個(gè)簡(jiǎn)單的 Row 組件包裹,具體地實(shí)現(xiàn)細(xì)節(jié),將在源碼分析中介紹:

[AppBar]----final bool? centerTitle;
toolbarOpacity 和 bottomOpacity 分別用來控制標(biāo)題欄和底欄的透明度,取值范圍是 [0 ~ 1],默認(rèn)是 1 不透明。一般來說很少有這種需求,了解一下即可:

---->[AppBar]----
final double? toolbarOpacity;
final double? bottomOpacity;
titleSpacing 是一個(gè) double 值,用于控制標(biāo)題欄和區(qū)域左側(cè)的間隔,默認(rèn)情況下根據(jù) Material 的風(fēng)格有一定的空間,該值為 16:


final double? titleSpacing;
titleSpacing 是一個(gè) double 值,用于控制左側(cè) leading 的區(qū)域?qū)挾龋J(rèn)情況下是 56,呈正方形:
final double? leadingWidth;
AppBar 樣式屬性
可以通過 shape 屬性設(shè)置 AppBar 形狀,如下是通過 RoundedRectangleBorder 設(shè)置的圓角矩形。另外 elevation 和 shadowColor 分別表示陰影的深度和陰影顏色:

參數(shù) | 類型 | 描述 |
---|---|---|
shadowColor | Color? | 陰影顏色 |
elevation | double | 影深 |
shape | ShapeBorder? | 形狀 |

另外通過去除陰影、設(shè)置背景色,也可以很輕松地?cái)[脫 Material 風(fēng)格。其中通過了 iconTheme 來配置 AppBar 中的默認(rèn)圖標(biāo)主題,這樣如果存在多個(gè)按鈕,方便統(tǒng)一配置,避免一個(gè)個(gè)設(shè)置的麻煩。actionsIconTheme 的圖標(biāo)樣式優(yōu)先作用于 actions 屬性中的組件。 另外,toolbarTextStyle 為工具條區(qū)域內(nèi)的所有文字通過默認(rèn)樣式,titleTextStyle 配置的默認(rèn)標(biāo)題文字主題,優(yōu)先級(jí)較高。
參數(shù) | 類型 | 描述 |
---|---|---|
backgroundColor | Color? | 背景色 |
iconTheme | IconThemeData? | 圖標(biāo)樣式 |
actionsIconTheme | IconThemeData? | 右側(cè)圖標(biāo)樣式 |
titleTextStyle | TextStyle? | 標(biāo)題文字樣式 |
toolbarTextStyle | TextStyle? | 工具條文字樣式 |
AppBar(
title: const Text('AppBar 組件'),
leading: BackButton(),
elevation: 0,
backgroundColor: Colors.white,
centerTitle: true,
iconTheme: IconThemeData(color: Colors.black),
titleTextStyle: TextStyle(color: Colors.black,fontSize: 16,fontWeight: FontWeight.bold),
actions: [
IconButton(onPressed: (){}, icon: Icon(Icons.refresh)),
IconButton(onPressed: (){}, icon: Icon(Icons.add)),
],
),
AppBar 的使用細(xì)節(jié)
AppBar 在構(gòu)造時(shí)可以傳入 automaticallyImplyLeading 屬性,用于控制是否在 leading 為 null 時(shí),根據(jù)場(chǎng)景自動(dòng)添加某些圖標(biāo): 比如 Scafflod 中 drawer 屬性非空時(shí),會(huì)自動(dòng)提供 leading,點(diǎn)擊時(shí)響應(yīng)事件打開 drawer。


還有當(dāng)跳轉(zhuǎn)界面時(shí),如果使用了 AppBar 并且未提供 leading,會(huì)自動(dòng)添加返回按鈕。如果不想啟用這個(gè)功能,將 automaticallyImplyLeading 置為 false 即可。
在 AppBar的使用過程中,有一個(gè)非常重要,可能很少人注意的一點(diǎn): AppBar 的背景色可以影響頂部狀態(tài)欄的顏色。比如默認(rèn)情況下背景色是藍(lán)色,狀態(tài)欄是白色:

如果背景色是白色,狀態(tài)欄就會(huì)是黑色,這樣就很方便。

如果不使用 AppBar,也能界面跳著跳著狀態(tài)欄就錯(cuò)亂了。比如類似下面的情況。通過源碼可以知道 AppBar 中會(huì)通過 AnnotatedRegion 維護(hù)狀態(tài)欄的顏色。

如果狀態(tài)欄的顏色和您預(yù)期的不同,可以通過 systemOverlayStyle 屬性來設(shè)置狀態(tài)欄的顏色,如下 light 會(huì)將狀態(tài)欄圖標(biāo)的顏色變白:
systemOverlayStyle: const SystemUiOverlayStyle(
statusBarIconBrightness:Brightness.light
),

關(guān)于 AppBar 的使用基本上就是這些,總的來看,AppBar 算是一個(gè)比較優(yōu)秀的組件,使用很靈活,能滿足絕大多數(shù)的頭部欄使用場(chǎng)景。如果您在日常開發(fā)中還自己用 Row 來拼裝,那不妨試試 AppBar 組件。
長(zhǎng)按右側(cè)二維碼
查看更多開發(fā)者精彩分享

"開發(fā)者說·DTalk" 面向中國開發(fā)者們征集 Google 移動(dòng)應(yīng)用 (apps & games)?相關(guān)的產(chǎn)品/技術(shù)內(nèi)容。歡迎大家前來分享您對(duì)移動(dòng)應(yīng)用的行業(yè)洞察或見解、移動(dòng)開發(fā)過程中的心得或新發(fā)現(xiàn)、以及應(yīng)用出海的實(shí)戰(zhàn)經(jīng)驗(yàn)總結(jié)和相關(guān)產(chǎn)品的使用反饋等。我們由衷地希望可以給這些出眾的中國開發(fā)者們提供更好展現(xiàn)自己、充分發(fā)揮自己特長(zhǎng)的平臺(tái)。我們將通過大家的技術(shù)內(nèi)容著重選出優(yōu)秀案例進(jìn)行谷歌開發(fā)技術(shù)專家 (GDE)?的推薦。

原文標(biāo)題:Flutter 組件集錄: AppBar 的使用 | 開發(fā)者說·DTalk
文章出處:【微信公眾號(hào):谷歌開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
谷歌
+關(guān)注
關(guān)注
27文章
6223瀏覽量
107517
原文標(biāo)題:Flutter 組件集錄: AppBar 的使用 | 開發(fā)者說·DTalk
文章出處:【微信號(hào):Google_Developers,微信公眾號(hào):谷歌開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
鴻蒙Flutter實(shí)戰(zhàn):07混合開發(fā)
2021華為開發(fā)者大會(huì)主題演講_王成錄PPT
華為開發(fā)者大會(huì)2021 華為開發(fā)者的年度盛會(huì)

Flutter 組件: Autocomplete 自動(dòng)填充 | 開發(fā)者說·DTalk
Flutter 3.3 之 SelectionArea 好不好用?用 "Bug" 帶您全面了解它 | 開發(fā)者說·DTalk
一文快速帶您了解 KMM、Compose 和 Flutter 的現(xiàn)狀 | 開發(fā)者說·DTalk
與 Flutter 共創(chuàng)未來 | Flutter Forward 活動(dòng)精彩回顧
Flutter 中國開發(fā)者大會(huì) | Flutter Forward Extended China
報(bào)名開啟 | 共赴一場(chǎng) Flutter 的春日宴
為了更好的 Flutter | 2023 第二季度開發(fā)者調(diào)研

創(chuàng)新不竭,探索不止 | 開發(fā)者說·DTalk 年中優(yōu)秀賞

社區(qū)說 | 精益求精: Flutter 技巧專題篇

【今晚開播】社區(qū)說 | 精益求精: Flutter 技巧專題篇

【開發(fā)者說】開發(fā)案例:使用canvas實(shí)現(xiàn)圖表系列之折線圖

【開發(fā)者說】HarmonyOS實(shí)踐之應(yīng)用狀態(tài)變量共享

評(píng)論