Flutter map 妙用及 .. 使用

前言

本篇文章對於熟悉 flutter 或者 dart 的小夥伴來講可能以爲比較簡單,可是對於初學者或者沒用過的小夥伴仍是有些收穫的。html

背景

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

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

那麼妙用在哪呢?github

統一處理

咱們在上節課說到了 Expanded 的比例佈局。express

源代碼以下:設計模式

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 能夠轉換爲以下代碼:app

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(),
    );

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

可是有時候可能咱們有 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 can't be used.
  valueBuffer.write("I")
              ^
main.dart:4:6:
Error: The method 'write' isn't 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 地址:👇
https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/tooltip_demo.dart

更多閱讀:
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 如何優雅的避空

相關文章
相關標籤/搜索