前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter 组件集录 | 全面认识 AppBar 组件 - 使用篇

Flutter 组件集录 | 全面认识 AppBar 组件 - 使用篇

作者头像
张风捷特烈
发布2022-10-31 11:01:05
1.1K0
发布2022-10-31 11:01:05
举报

theme: cyanosis

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 6 天,点击查看活动详情


1. 前言

说起 AppBar 组件,大家都比较熟悉,默认情况下是一个 Material 风格的头部标题栏。可能有人疑惑,这么简单的东西,有什么好说的?其实该组件一些重要的属性很多人都不知道,另外在使用过程中有一些细节,本文将结合 使用源码 来详细探讨一下 AppBar 组件。

如下是 Material2Material3 风格下默认的 AppBar 展示效果:

Material2

Material3

代码语言:javascript
复制
AppBar(title: const Text('AppBar 组件')),

1. AppBar 组件的高度

对于 AppBar 来说,最重要的莫过于它的 高度,那它的高度是如何确定的呢?这就不得不说 PreferredSizeWidget 一族的组件了。如下可见,它实现了 PreferredSizeWidget 类:

image.png
image.png

如下所示,PreferredSizeWidget 是一个抽象类,其中定义了 preferredSize 抽象 get 方法,返回 Size 对象。也就是说该族的组件是需要预先设定尺寸的:

代码语言:javascript
复制
abstract class PreferredSizeWidget implements Widget {
  Size get preferredSize;
}

所以 AppBar 既然实现 PreferredSizeWidget,就必然实现 preferredSize 方法,返回尺寸。所以根据这个线索可以知道高度是如何确定的:AppBar 中定义了 preferredSize 成员,所以抽象的 get 方法,将获取该成员:

AppBar 构造方法中,preferredSize 被赋值为 _PreferredAppBarSize 对象,其中有两个入参: toolbarHeight,和 bottom 的高度。

image.png
image.png

如下是 _PreferredAppBarSize 类的定义,它继承自 Size,是一个专为 AppBar 高度派生的类。Size#fromHeight 构造中,宽度无限大,高度是 toolbarHeightbottomHeight 的和。其中 toolbarHeight 如果为空,会取 kToolbarHeight, 值为 56 :

image.png
image.png
代码语言:javascript
复制
---->[AppBar]----
@override
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 组件,在标题的底部展示。如下所示,所以可以说, AppBar组件的高度就是 toolbarHeightbottom 组件高度之和。

image.png
image.png
代码语言:javascript
复制
---->[AppBar]----
final PreferredSizeWidget? bottom;
final double? toolbarHeight;

另外,可以通过参数指定 toolbarHeight 的值,如下是 40 的效果,可以看出标题的高度变小,但并不会影响 bottom

image.png
image.png
代码语言:javascript
复制
AppBar(
  title: const Text('AppBar 组件'),
  toolbarHeight: 40,
),

关于 AppBar 的高度需要注意的就是这些,一般来说 AppBar 作为 Scaffold#appBar 属性的钦定组件使用,不会在外界单独使用。


2. AppBar 组件的部位

一个普通的 AppBar 可以包含如下四个部位, leading 是左侧组件,title 是中间组件,actions 的右侧组件列表。 bottom 是底部组件:

image.png
image.png
代码语言:javascript
复制
---->[AppBar]----
final PreferredSizeWidget? bottom;
final Widget? leading;
final Widget? title;
final List<Widget>? actions;

通过查看布局效果可以更清晰地看出 AppBar 各部位的占位情况,

image.png
image.png

另外,还有一个Widlget 类型的 flexibleSpace 属性,在源码实现的过程中,该组件将通过 Stack 叠放在 AppBar 下方。效果如下,如果普通的 AppBar 底部用贴图的需求,可以使用这个属性:

image.png
image.png
代码语言:javascript
复制
---->[AppBar]----
final Widget? flexibleSpace;

3. 部位相关控制属性

下面介绍一些关于部位的属性: centerTitle 是一个 bool 值,可以控制 title 是否居中显示。这个是在整体的居中,所以 AppBar 的标题栏并不是一个简单的 Row 组件包裹,具体地实现细节,将在源码分析中介绍:

image.png
image.png
代码语言:javascript
复制
---->[AppBar]----
final bool? centerTitle;

toolbarOpacitybottomOpacity 分别用来控制标题栏和底栏的透明度,取值范围是 [0 ~ 1],默认是 1 不透明。一般来说很少有这种需求,了解一下即可:

image.png
image.png
代码语言:javascript
复制
---->[AppBar]----
final double? toolbarOpacity;
final double? bottomOpacity;

titleSpacing 是一个 double 值,用于控制标题栏和区域左侧的间隔,默认情况下根据 Material 的风格有一定的空间,该值为 16 :

image.png
image.png

所以想要消除这个间距,让 titleSpacing 置零即可:

image.png
image.png
代码语言:javascript
复制
final double? titleSpacing;

titleSpacing 是一个 double 值,用于控制左侧 leading 的区域宽度,默认情况下是 56, 呈正方形 :

image.png
image.png
代码语言:javascript
复制
final double? leadingWidth;

4. AppBar 样式属性

可以通过 shape 属性设置 AppBar 形状,如下是通过 RoundedRectangleBorder 设置的圆角矩形。关于ShapeBorder 相关的使用,可以参考另一篇文章: 【Path在手,天下我有】。另外 elevationshadowColor 分别表示阴影的深度和阴影颜色:

image.png
image.png

参数

类型

描述

shadowColor

Color?

阴影颜色

elevation

double

影深

shape

ShapeBorder?

形状


image.png
image.png

另外通过去除阴影、设置背景色,也可以很轻松地摆脱 Material 风格。其中通过了 iconTheme 来配置 AppBar 中的默认图标主题,这样如果存在多个按钮,方便统一配置,避免一个个设置的麻烦。actionsIconTheme 的图标样式优先作用于 actions 属性中的组件。

另外,toolbarTextStyle 为工具条区域内的所有文字通过默认样式,titleTextStyle 配置的默认标题文字主题,优先级较高。

参数

类型

描述

backgroundColor

Color?

背景色

iconTheme

IconThemeData?

图标样式

actionsIconTheme

IconThemeData?

右侧图标样式

titleTextStyle

TextStyle?

标题文字样式

toolbarTextStyle

TextStyle?

工具条文字样式

代码语言:javascript
复制
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)),
  ],
),

5. AppBar 的使用细节

AppBar 在构造时可以传入 automaticallyImplyLeading 属性,用于控制是否在 leadingnull 时,根据场景自动添加某些图标:比如 Scaffloddrawer 属性非空时,会自动提供 leading,点击时响应事件打开 drawer

image.png
image.png
image.png
image.png

还有当跳转界面时,如果使用了 AppBar 并且未提供 leading ,会自动添加返回按钮。如果不想启用个功能,将 automaticallyImplyLeading 置为 false 即可。


AppBar 的使用过程中,有一个非常重要,可能很少人注意的一点: AppBar 的背景色可以影响顶部状态栏的颜色。比如默认情况下背景色是蓝色,状态栏是白色:

image.png
image.png

如果背景色是白色,状态栏就会是黑色,这样就很方便。

image.png
image.png

如果不使用 AppBar,也能界面跳着跳着状态栏就错乱了。比如类似下面的情况。通过源码可以知道 AppBar 中会通过 AnnotatedRegion 维护状态栏的颜色。

image.png
image.png

如果状态栏的颜色和你预期的不同,可以通过 systemOverlayStyle 属性来设置状态栏的颜色,如下 light 会将状态栏图标的颜色变白:

代码语言:javascript
复制
systemOverlayStyle: const SystemUiOverlayStyle(
    statusBarIconBrightness:Brightness.light
),
image.png
image.png

关于 AppBar 的使用基本上就是这些,总的来看, AppBar 算是一个比较优秀的组件,使用很灵活,能满足绝大多数的头部栏使用场景。如果你在日常开发中还自己用 Row 来拼装,那不妨试试 AppBar 组件。下一篇将通过分析 AppBar 源码的实现,来分析一下更细致的实现逻辑,从中吸收一下处理的小技巧。 那本文就到这里,谢谢观看 ~


更多 Flutter 内置组件介绍,欢迎关注 《Flutter 组件集录》 专栏。

  • @张风捷特烈 2022.10.20 未允禁转
  • 我的 公众号: 编程之王
  • 我的 github 主页 :  toly1994328
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-10-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • theme: cyanosis
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档