Flutter map 妙用及 .. 使用

前言

本篇文章對於熟悉 flutter 或者 dart 的小夥伴來說可能覺得比較簡單,但是對於初學者或者沒用過的小夥伴還是有些收穫的。

背景

說到 map 妙用的發現,還要歸功於 Tooltip 的研究。

在研究這個 Widget 的時候,看到了它的源碼 demo,所以發現了這個 map 的妙用。

那麼妙用在哪呢?

統一處理

我們在上節課說到了 Expanded 的比例布局。

源代碼如下:

return Column(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.blue,
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.grey,
),
),
],
);

使用 map 可以轉換為如下代碼:

return Column(
children: <Widget>[
Container(
color: Colors.red,
),
Container(
color: Colors.blue,
),
Container(
color: Colors.grey,
),
]
//.map((Widget widget){ 也是可以的
.map<Widget>((Widget widget){
return Expanded(
flex: 1,
child: widget,
);
})
.toList(),
);

這樣就統一管理了,減少了冗餘代碼,更加優雅了~

但是有時候可能我們有 10 個子組件,但是可能有 8 個需要統一處理,有兩個不需要,怎麼辦呢?

我們可以利用 widget 的 標識屬性 key 來處理。

以上面代碼為例,假設我希望第一個子組件佔兩塊比例,另外兩個都佔一塊比例。

可以修改代碼如下:

return Column(
children: <Widget>[
Container(
key: Key(1),
color: Colors.red,
),
Container(
color: Colors.blue,
),
Container(
color: Colors.grey,
),
]
//.map((Widget widget){ 也是可以的
.map<Widget>((Widget widget){
print(widget.key);
int flex = 1;
if (widget.key == Key(1)) {
flex = 2;
}
return Expanded(
flex: flex,
child: widget,
);
})
.toList(),
);

可以看到我們通過 key 對第一個子組件做了區分處理。

另外正如學習設計模式的時候,不要為了設計而設計。

Map 的妙用能夠使代碼更優雅,但是我們也不要為了優雅而優雅。

而是真的適用你的場景,我們再使用。判別就是能否減少冗餘代碼。

其實上面的 map 用法有點讓我想起 RxJava 裡面 map 的使用。

我們可以認為上面的 map 是對一個列表裡的每個元素按照特定規則進行處理。

.. Operator

.. 操作符在 dart 裡面的描述是 cascade,翻譯出來是級聯。

這邊的一個用法其實是鏈式寫法。

什麼意思呢?

我們舉 StringBuffer 這個例子。

dart 裡面的 StringBuffer 和 java 裡面的 StringBuffer 是有差別的。

首先我們看下下面的字元串連接用 java 實現,代碼如下:

StringBuffer valueBuffer = new StringBuffer();
valueBuffer.append("I")
.append(" ")
.append("love")
.append(" ")
.append("Flutter");
System.out.println(valueBuffer.toString());

如果用 dart 實現的話,首先第一個點就是 dart 裡面的 StringBuffer 沒有 append 方法,取而代之的是 write 方法。

你以為只是上面的 append 改為 write?

如果你將 append 改為 write,如下

StringBuffer valueBuffer = new StringBuffer();
valueBuffer.write("I")
.write(" ")
.write("love")
.write(" ")
.write("Flutter");
print(valueBuffer.toString());

編譯器會提示下面錯誤:

The expression here has a type of void, and therefore cannot be used.

如果運行,也會報下面錯誤:

Error compiling to JavaScript:
DetailedApiRequestError(status: 400, message: main.dart:3:15:
Error: This expression has type void and cant be used.
valueBuffer.write("I")
^
main.dart:4:6:
Error: The method write isnt defined for the class void.
.write(" ")
^^^^^
Error: Compilation failed.
)

很明顯,write 方法返回類型是 void,因此不能這樣寫。

所以這個時候 .. 的作用就出現了,你只需要把 .append 改為 ..write 即可,如下:

StringBuffer valueBuffer = new StringBuffer();
valueBuffer..write("I")
..write(" ")
..write("love")
..write(" ")
..write("Flutter");
print(valueBuffer.toString());

上面所有代碼輸出都是一樣的,就是 I love Flutter

另外 Tooltip Demo 地址:??

github.com/flutter/flut

更多閱讀:

Flutter 即學即用系列博客

Flutter 即學即用系列博客——01 環境搭建

Flutter 即學即用系列博客——02 一個純 Flutter Demo 說明

Flutter 即學即用系列博客——03 在舊有項目引入 Flutter

Flutter 即學即用系列博客——04 Flutter UI 初窺

Flutter 即學即用系列博客——05 StatelessWidget vs StatefulWidget

Flutter 即學即用系列博客——06 超實用 Widget 集錦

Flutter 即學即用系列博客——07 RenderFlex overflowed 引發的思考

Flutter & dart

dart 如何優雅的避空


推薦閱讀:

TAG:Flutter | Dart | 移動互聯網 |