本篇文章对于熟悉 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 是对一个列表里的每个元素按照特定规则进行处理。
.. 操作符在 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