前言
說起 AppBar 組件,大家都比較熟悉,默認(rèn)情況下是一個 Material 風(fēng)格的頭部標(biāo)題欄。可能有人疑惑,這么簡單的東西,有什么好說的?其實該組件一些重要的屬性很多人都不知道,另外在使用過程中有一些細(xì)節(jié),本文將結(jié)合使用和源碼來詳細(xì)探討一下 AppBar 組件。
如下是 Material 2 和 Material 3 風(fēng)格下默認(rèn)的 AppBar 展示效果:Material 2 | Material 3 |
---|---|
AppBar(title: const Text('AppBar 組件')),
AppBar 組件的高度
對于 AppBar 來說,最重要的莫過于它的高度,那它的高度是如何確定的呢?這就不得不說 PreferredSizeWidget 一族的組件了。如下可見,它實現(xiàn)了 PreferredSizeWidget 類:
如下所示,PreferredSizeWidget是一個抽象類,其中定義了 preferredSize 抽象 get 方法,返回 Size 對象。也就是說該族的組件是需要預(yù)先設(shè)定尺寸的:
abstract class PreferredSizeWidget implements Widget {
Size get preferredSize;
}
所以 AppBar 既然實現(xiàn) PreferredSizeWidget,就必然實現(xiàn) preferredSize 方法,返回尺寸。所以根據(jù)這個線索可以知道高度是如何確定的: AppBar 中定義了preferredSize 成員,所以抽象的 get 方法,將獲取該成員:
在 AppBar 構(gòu)造方法中,preferredSize 被賦值為 _PreferredAppBarSize 對象,其中有兩個入?yún)? toolbarHeight,和 bottom 的高度。
如下是 _PreferredAppBarSize 類的定義,它繼承自 Size,是一個專為 AppBar 高度派生的類。Size#fromHeight 構(gòu)造中,寬度無限大,高度是 toolbarHeight 和 bottomHeight 的和。其中 toolbarHeight 如果為空,會取 kToolbarHeight,值為 56: ?
---->[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)題的高度變小,但并不會影響 bottom。
?
AppBar(
title: const Text('AppBar 組件'),
toolbarHeight: 40,
),
關(guān)于 AppBar 的高度需要注意的就是這些,一般來說 AppBar 作為 Scaffold#appBar 屬性的欽定組件使用,不會在外界單獨使用。
AppBar 組件的部位
一個普通的 AppBar可以包含如下四個部位,leading 是左側(cè)組件,title 是中間組件,actions 的右側(cè)組件列表。bottom 是底部組件:
?
---->[AppBar]----
final PreferredSizeWidget? bottom;
final Widget? leading;
final Widget? title;
final List? actions;
通過查看布局效果可以更清晰地看出 AppBar 各部位的占位情況,
?另外,還有一個 Widlget 類型的 flexibleSpace 屬性,在源碼實現(xiàn)的過程中,該組件將通過 Stack 疊放在 AppBar下方。效果如下,如果普通的 AppBar 底部用貼圖的需求,可以使用這個屬性:
?
[AppBar]----final Widget? flexibleSpace;
部位相關(guān)控制屬性
下面介紹一些關(guān)于部位的屬性: centerTitle 是一個 bool 值,可以控制 title 是否居中顯示。這個是在整體的居中,所以 AppBar 的標(biāo)題欄并不是一個簡單的 Row 組件包裹,具體地實現(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 是一個 double 值,用于控制標(biāo)題欄和區(qū)域左側(cè)的間隔,默認(rèn)情況下根據(jù) Material 的風(fēng)格有一定的空間,該值為 16:
所以想要消除這個間距,讓 titleSpacing 置零即可: ?
final double? titleSpacing;
titleSpacing 是一個 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è)置背景色,也可以很輕松地擺脫 Material 風(fēng)格。其中通過了 iconTheme 來配置 AppBar 中的默認(rèn)圖標(biāo)主題,這樣如果存在多個按鈕,方便統(tǒng)一配置,避免一個個設(shè)置的麻煩。actionsIconTheme 的圖標(biāo)樣式優(yōu)先作用于 actions 屬性中的組件。 另外,toolbarTextStyle 為工具條區(qū)域內(nèi)的所有文字通過默認(rèn)樣式,titleTextStyle 配置的默認(rèn)標(biāo)題文字主題,優(yōu)先級較高。
參數(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)造時可以傳入 automaticallyImplyLeading 屬性,用于控制是否在 leading 為 null 時,根據(jù)場景自動添加某些圖標(biāo): 比如 Scafflod 中 drawer 屬性非空時,會自動提供 leading,點擊時響應(yīng)事件打開 drawer。
還有當(dāng)跳轉(zhuǎn)界面時,如果使用了 AppBar 并且未提供 leading,會自動添加返回按鈕。如果不想啟用這個功能,將 automaticallyImplyLeading 置為 false 即可。
在 AppBar的使用過程中,有一個非常重要,可能很少人注意的一點: AppBar 的背景色可以影響頂部狀態(tài)欄的顏色。比如默認(rèn)情況下背景色是藍(lán)色,狀態(tài)欄是白色:
如果背景色是白色,狀態(tài)欄就會是黑色,這樣就很方便。
如果不使用 AppBar,也能界面跳著跳著狀態(tài)欄就錯亂了。比如類似下面的情況。通過源碼可以知道 AppBar 中會通過 AnnotatedRegion 維護狀態(tài)欄的顏色。
如果狀態(tài)欄的顏色和您預(yù)期的不同,可以通過 systemOverlayStyle 屬性來設(shè)置狀態(tài)欄的顏色,如下 light 會將狀態(tài)欄圖標(biāo)的顏色變白:
systemOverlayStyle: const SystemUiOverlayStyle(
statusBarIconBrightness:Brightness.light
),
關(guān)于 AppBar 的使用基本上就是這些,總的來看,AppBar 算是一個比較優(yōu)秀的組件,使用很靈活,能滿足絕大多數(shù)的頭部欄使用場景。如果您在日常開發(fā)中還自己用 Row 來拼裝,那不妨試試 AppBar 組件。
長按右側(cè)二維碼
查看更多開發(fā)者精彩分享
"開發(fā)者說·DTalk" 面向中國開發(fā)者們征集 Google 移動應(yīng)用 (apps & games)?相關(guān)的產(chǎn)品/技術(shù)內(nèi)容。歡迎大家前來分享您對移動應(yīng)用的行業(yè)洞察或見解、移動開發(fā)過程中的心得或新發(fā)現(xiàn)、以及應(yīng)用出海的實戰(zhàn)經(jīng)驗總結(jié)和相關(guān)產(chǎn)品的使用反饋等。我們由衷地希望可以給這些出眾的中國開發(fā)者們提供更好展現(xiàn)自己、充分發(fā)揮自己特長的平臺。我們將通過大家的技術(shù)內(nèi)容著重選出優(yōu)秀案例進行谷歌開發(fā)技術(shù)專家 (GDE)?的推薦。
?點擊屏末|閱讀原文|即刻報名參與 "開發(fā)者說·DTalk"
原文標(biāo)題:Flutter 組件集錄: AppBar 的使用 | 開發(fā)者說·DTalk
文章出處:【微信公眾號:谷歌開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
-
谷歌
+關(guān)注
關(guān)注
27文章
6141瀏覽量
105087
原文標(biāo)題:Flutter 組件集錄: AppBar 的使用 | 開發(fā)者說·DTalk
文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論