在工作中我們可能會寫出以下代碼:
class MyExampleState extends State<MyExample> {
bool loading = false;
Data? data;
@override
Widget build(BuildContext context) {
return Scaffold(
body: loading
? const CircularProgressIndicator()
: (data == null ? const Text('error_area') : const Text('content_area')),
);
}
}
這樣的三元表達式看起來很丑理茎,如果條件再多點,就很難維護了管嬉。
如果你對 Dart 語言了解得比較深的話皂林,應該知道在 Dart 的集合中是可以使用 if、for 循環(huán)語法的蚯撩。這個特性是 Dart 專為 Flutter 定制的础倍,Dart 一直聲稱自己是一個為全平臺構(gòu)建快速應用的客戶端優(yōu)化的編程語言。后面我們有機會可以來仔細盤點一下 Dart 都為客戶端開發(fā)(主要是 Flutter)做了哪些優(yōu)化胎挎。
這種 if 和 for 語法標準的叫法是集合中的 if 和集合中的 for沟启。它們是 if 和 for 語句的閹割版。比如兩者都沒法使用花括號 {} 來把語句體包起來犹菇。后者你沒法使用 break德迹、continue。下面的示例幾乎展現(xiàn)了它們的全部語法:
List<Widget> widgets = [
if (loading)
const CircularProgressIndicator()
else if (data == null)
const Text('error_area')
else
const Text('content_area'),
for (int i = 0; i < 10; i++) Text('item_$i')
];
集合中的 if 和集合中的 for相比第一個例子中的三元表達式要好多了揭芍,條件再多也會很清晰胳搞。很遺憾的是它只能在集合中使用,而在大量的場景下,方法的形參接收的是單一變量而非集合肌毅。能不能針對這類方法也用上集合中的 if 和集合中的 for呢筷转?答案是肯定的!看代碼:
class MyExampleState extends State<MyExample> {
bool loading = false;
Data? data;
@override
Widget build(BuildContext context) {
return Scaffold(
body: [
if (loading)
const CircularProgressIndicator()
else if (data == null)
const Text('error_area')
else
const Text('content_area')
][0],
);
}
}
盡管 body 只接收一個 Widget悬而,但我們構(gòu)造了一個集合呜舒,并將集合的第 0 個元素賦值給 body,而條件表達式的作用就是去生成第 0 個元素笨奠。是不是很 nice袭蝗?這種用法可以擴展到所有只接收單一參數(shù)而非集合的地方,比如 color般婆、width呻袭、height 的設置。
除了集合中的 if 和集合中的 for以外腺兴,2.3 版本的 Dart 還引入了 擴展操作符(...)和 空感知擴展操作符(...?),它們提供了一種將多個元素插入集合的簡潔方法廉侧,比如:
var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);
以往我們封裝的 buildXXX 方法只返回一個 Widget页响,有了這個特性以后,我們可以返回一個 List<Widget>段誊。并使用 ... 操作符將其添加到 children 列表中:
class MyExampleState extends State<MyExample> {
bool loading = false;
Data? data;
List<Widget> buildTitleArea() {
return [];
}
Widget buildBody() {
return const Text('body_area');
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ConstraintLayout(
children: [
...buildTitleArea(),
buildBody(),
],
),
);
}
}
結(jié)合集合中的 if闰蚕,我們可以實現(xiàn)對多個 Widget 的顯示、隱藏连舍。
以上所講的這些没陡,其實在 Flutter ConstraintLayout 中有更好的辦法,因為它創(chuàng)造性的支持了開放式語法(Open Grammar)索赏,你可以使用 Dart 的任何語法來組織子元素:
class OpenGrammarExample extends StatelessWidget {
const OpenGrammarExample({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: ConstraintLayout().open(() {
if (DateTime.now().millisecond % 2 == 0) {
Container(
color: Colors.red,
).applyConstraint(
size: 200,
centerTo: parent,
);
} else {
Container(
color: Colors.yellow,
).applyConstraint(
size: 200,
centerTo: parent,
);
}
for (int i = 0; i < 5; i++) {
Row().open(() {
for (int j = 0; j < 10; j++) {
Text("$i x $j").enter();
const SizedBox(
width: 20,
).enter();
}
}).applyConstraint(
height: 100,
left: parent.left.margin(100),
top: i == 0 ? parent.top : sId(-1).bottom,
);
}
int i = 0;
while (i < 100) {
Text("$i").applyConstraint(
left: parent.left,
top: i == 0 ? parent.top : sId(-1).bottom,
);
i++;
}
}),
);
}
}
是不是很 nice盼玄?
好了,這篇文章就到這里潜腻,歡迎在評論區(qū)交流埃儿,我是中國第一位 Android & Flutter 雙料 GDFE,關注我的公眾號:FlutterFirst融涣,帶你起飛童番!