Flutter组件详解与实战
上QQ阅读APP看书,第一时间看更新

1.3.3 Center

在所有对齐方式中,居中无疑是最常见的情况,因此Flutter框架从Align组件继承了一个新的Center组件,专门负责居中。Center组件的实现方法也是直接在构造函数里调用父类,仅此而已。在Flutter框架的源码中可以看到,Center组件的全部代码只有以下这短短几行:

class Centerex tends Align{
  const Center({double widthFactor,double heightFactor, Widget child})
  : super(widthFactor: widthFactor,heightFactor: heightFactor, child: child);
}

由此可见,Center组件总共有3个参数:child(子组件)、widthFactor (宽度倍数)和heightFactor(高度倍数),用法与1.3.2节介绍的Align组件完全相同,在此不赘述。

Dart Tips语法小贴士

位置参数、可选位置参数和命名参数

在Center组件的构造函数里可以看到传入的3个参数被花括号{}包围,这是Dart里面命名参数的表达方式。因为命名参数在使用的时候不需要在意位置,且不必传的参数可以直接不填,需要传的参数也会打上参数名,可读性极高,因此Flutter组件大量使用命名参数。

Dart语法中,函数的参数共有3类,分别是必传的位置参数、可选的位置参数及命名参数。在定义函数时这3类参数可以随意混合使用。

第1类必传位置参数,其实就是传统编程语言里最常见的必填参数,调用时需要按照顺序传入。例如函数add(intx,inty)就定义了xy这2个位置参数。调用时,例如add (2,3),程序会按照顺序将x赋值为2,将y赋值为3。

第2类可选位置参数,用方括号表示,并且可以提供默认值。如函数log(double x,[int base=10])就表示小数x必传(且为第1个参数),而整数base参数选传(且为第2个参数)。若调用时没有传入第2个参数,则取默认值10。例如log(20.0)或者log(20.0,2)都是合法的调用。

第3类命名参数,需要用花括号表示,默认所有的命名参数都是可选的,因此也可以设置默认值。如果需要与位置参数混合使用,则必须把位置参数写在最前面。只有等所有的位置参数都写完了,才可以在花括号里面写命名参数。例如函数log(double x,{intbase=10}),即表示x必传,而后面的参数可以选择省略。如果需要传参数,则一定要注明参数的名字再传值。如log(20,base:2)等。Flutter于2021年3月3日起正式支持空安全,并添加了required关键字,因此开发者也可以使用必传的命名参数,例如log({required double x,int base=10})就可使x参数必传。

在Flutter 2.0之前,必传的命名参数通过@required 标注的方式勉强实现。例如可写log({@required double x,int base=10}),这样如果调用时不传入x值,就会出现警告,但不会报错。如果程序员没有注意或选择性忽视了警告,就可能出现空值,因此不少旧代码都会利用assert确保必填的参数都已被赋值。

与Align组件一样,Center的自身尺寸也默认为越大越好,尽量占满父级组件的全部可用空间,以便更好地将自己的子组件居中摆放。Center与Align组件相比,实际上只少了alignment参数,因为它不支持其他的对齐方式,而恰好Align组件不传alignment参数时,其默认行为也是居中,于是代码中出现的所有Center组件均可直接替换为Align组件。这样做除了牺牲可读性之外,运行起来不会有任何区别。由此可见,Center存在的意义就是为了帮助代码的可读性,属于像“语法糖”一样的便利组件。


(1) https://flutter.dev/docs/development/ui/widgets-intro

(2) https://api.flutter.dev/flutter/dart-ui/Window/devicePixelRatio.html

(3) https://api.flutter.dev/flutter/material/FlutterLogo/colors.html

(4) https://groups.google.com/forum/#!topic/flutter-dev/XMHE0XdsXxI

(5) https://github.com/flutter/flutter/issues/19445

(6) https://api.flutter.dev/flutter/painting/FractionalOffset-class.html