前言

本篇文章对于熟悉 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 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 地址:

Flutter map 妙用及 .. 使用的更多相关文章

  1. Flutter Map<String, dynamic> 、List<String> a-z 排序

    字符串从 a-z 排序. Map<String, String> map = XXX, List<String> keys = map.keys.toList(); // ke ...

  2. Flutter 即学即用系列博客——09 EventChannel 实现原生与 Flutter 通信(一)

    前言 紧接着上一篇,这一篇我们讲一下原生怎么给 Flutter 发信号,即原生-> Flutter 还是通过 Flutter 官网的 Example 来讲解. 案例 接着上一次,这一次我们让原生 ...

  3. Flutter 即学即用系列博客——08 MethodChannel 实现 Flutter 与原生通信

    背景 前面我们讲了很多 Flutter 相关的知识点,但是我们并没有介绍怎样实现 Flutter 与原生的通信. 比如我在 Flutter UI 上面点击了一个按钮,我希望原生做一些处理,那么原生怎么 ...

  4. 记录一个python公式罗列的方法 join()方法和map()方法的妙用

    题干: 怎样将一个列表中的元素读出,并列出计算式子 比如:[,,,] 输出:+++ = 列表中的元素个数不定 小白和大神的方法: #小白的 numlist=[,,,] sum1='' cal='+' ...

  5. new Map的妙用

    const actions = new Map([ [1, ['processing','IndexPage']], [2, ['fail','FailPage']], [3, ['fail','Fa ...

  6. Flutter Dart List.map() 获取下标

    class HomePageState extends State{ final topTitles = ['审批单', '机票列表', '客服']; final topIcons = ['asset ...

  7. flutter 中 List 和 Map 的用法

    list集合 在Dart中,数组是List对象,因此大多数人只是将它们称为List.以下是一个简单的Dart的List: 创建一个int类型的list List list = [10, 7, 23]; ...

  8. 【源码篇】Flutter GetX深度剖析 | 我们终将走出自己的路(万字图文)

    前言 人心中的成见是一座大山,任你怎么努力都休想搬动. 这是电影<哪吒>里申公豹说的一句话,也是贯彻整部电影的一个主题:或许这句话引起了太多人的共鸣:35岁职场危机,大厂卡本科学历,无房无 ...

  9. EF6 Power Tools的妙用和问题

    环境:vs2013+EF:6.1.3.0+Power Tools:Beta 4 power tools:是一个反向工程,在已有数据库的情况下,可以利用它生成Code Frist模式的代码. 问题: 它 ...

随机推荐

  1. JDK--box和unbox

    目录 什么是装箱.拆箱 基本类型和包装类型 为什么会有基本类型? 为什么还要有包装类型 两者区别 两者互转 源码分析(JDK1.8版本) valueOf方法 1.Integer.Short.Byte. ...

  2. Docker最全教程之使用 Visual Studio Code玩转Docker(二十)

    前言 VS Code是一个年轻的编辑器,但是确实是非常犀利.通过本篇,老司机带你使用VS Code玩转Docker——相信阅读本篇之后,无论是初学者还是老手,都可以非常方便的玩转Docker了!所谓是 ...

  3. 基于Vue2-Calendar改进的日历组件(含中文使用说明)

    一,前言 我是刚学Vue的菜鸟,在使用过程中需要用到日历控件,由于项目中原来是用jQuery写的,因此用了bootstarp的日历控件,但是配合Vue实在有点蛋疼,不够优雅…… 于是网上搜了好久找到了 ...

  4. Android底部导航栏(可滑动)----TabLayout+viewPager

    [TabLayout] ①TabLayout是选项卡,在屏幕空间有限的情况下,对不同的空间进行分组.属于android support design,更多的用于新闻上,如果放在底部也可做底部导航栏 ② ...

  5. java.lang.UnsatisfiedLinkError:dlopen failed: “**/*/arm/*.so” has unexpected e_machine: 3

    转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/10458448.html 今天在做APP的时候使用so库,可结果一加载so库的时候便发生了这个莫名其妙的错 ...

  6. 如何利用MongoDB实现高性能,高可用的双活应用架构?

    投资界有一句至理名言——“不要把鸡蛋放在同一个篮子里”.说的是投资需要分解风险,以免孤注一掷失败之后造成巨大的损失. 转发来自 如何利用MongoDB实现高性能,高可用的双活应用架构?http://d ...

  7. 设置Mac 终端走代理

    1.打开终端执行:export http_proxy=socks5://127.0.0.1:1080 这个只能在当前终端执行一次退出后就需要重新设置 如果需要开机自动设置,把上面的代码加到~/.bas ...

  8. OutOfMemoryError/OOM/内存溢出异常实例分析--虚拟机栈和本地方法栈溢出

    关于虚拟机栈和本地方法栈,在JVM规范中描述了两种异常: 1.如果线程请求的栈深度大于JVM所允许的深度,将抛出StackOverflowError异常: 2.如果虚拟机在扩展栈时无法申请到足够的内存 ...

  9. 通信(二):进程间通信之socket

    一.为什么要学习socket? 我们打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?我们用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket.本地的进程间通 ...

  10. GetForegroundWindow获取的是托管进程ApplicationFrameHost,而不是真正的进程,比如XD软件

    问题描述 最近做一个实时检测系统当前激活进程的软件,Photoshop.PPT.Word都没有问题,但是无法检测到XD软件的进程,返回的仅仅是ApplicationFrameHost进程,经过研究发现 ...