fluttering Flutter( 三 )


指定类型
var
但和 JavaScript 不同的是 , 以下代码在 JavaScript 是不会报错的 , 但在 Dart 里会报错:
Object
如果非要上面这样写 , 那也可以 。把 var 换成 Object 就不报错了:
和 Java 类似 , Object 是所有对象的根基类 。但是这样的话 , 如果想打印一下 num 的字符串长度 , 是会报错的:
因为 length 是属于 String 的 , 但系统只知道 num 是一个对象 , 并不知道它是一个 String 。
dynamic
如果还是非要这样写 , 那也可以 。Dart 有一个特有的关键字 dynamic , 把 Object 改成 dynamic 就不报错了:
我们运行一下这个文件 , 可以在控制台看到正确打印出了字符串长度 。
函数
dynamic
在 Dart 里 , 函数也是可以不写返回类型的 , 不写的话会被当做 dynamic 来处理 。这样的话 , 函数的类型就是 return 的类型 , 如果没有 return 则是 void 类型 。比如可以这样:
运行之后是能正确打印出字符串长度的 。
用于传参
Dart 里的函数也是一个对象 , 所以可以把函数作为参数来传递 , 比如:
可选参数
在 Dart 的函数传参里 , 有一个叫可选参数的概念 , 我们以文字控件 Text 为例 , 在源码里可以看到 Text 的构造函数是这样的:
首先 , 在参数里有一个 data , 它是要显示的文字内容 , 是一个必填项 。而 data 后面的一堆参数 , 是用一个大括号括起来的 , 这些参数就叫做可选参数 , 意思是这些参数可传可不传 。
假如我们要显示一个比较长的文字 , 又想限制它最多显示两行 , 就可以这样来创建一个 Text:
可选参数 , 在 Flutter 里面用的非常多 。
异步
Future
在 Dart 里使用 Future 来处理异步任务 , 比如我们现在延时一秒打印 666 , 代码如下:
Future 的语法和 Promise 非常像 。任务执行成功会调用 then , 执行失败会调用 catchError , 而无论成功还是失败 , 都会调用 whenComplete 。
async/await
如果你不喜欢上面那种写法 , 或者是想把异步转成同步 , 就可以用 async 和 await 这两个关键字来转换 。
我们把上面的代码转换一下 , 写一个 getString 方法 , 返回的类型是 Future , 它会延时返回一个字符串 。在 main 函数后面加上 async 关键字 , 在 getString() 前面加上 await , 代码如下:
运行之后可以看到 , 能正常延时一秒后 , 把字符串打印出来 。这里 getString() 返回的类型是 Future , 而 await getString() 则是返回了延时之后返回的字符串 。await 要在 async 的函数里面才能使用 。
async 和 await 其实是一个语法糖 , 它最终也是转换成 Future 调用链的形式执行的 。
接下来回到 Flutter , Flutter 里最重要的一个概念是 Widget(下面翻译作控件) 。
在原生开发里面 , 我们可能会在界面上区分 , 这是一个 View , 这是一个 Layout , 这是一个 View Controller 。但在 Flutter 里面 , 它们全都属于一个统一的模型 Widget 。可以说 , 在 Flutter 界面里 , 所有东西都是 Widget 。
以前学面向对象的时候 , 我们都听过一句话 , 叫万物皆对象 。我这里套用一下 , 在 Flutter 里 ,  万物皆控件。
具体有哪些控件 , 我做了一下简单的分类 。
根控件
所有的控件都属于StatefulWidget或StatelessWidget。它们的区别是 , StatefulWidget 拥有状态State  , 而 StatelessWidget 没有 。
StatefulWidget
当一个控件是可变的时候 , 就要使用 StatefulWidget 来构建 。StatefulWidget 本身不可变 , 但它持有的状态 State 是可变的 。
StatelessWidget
当一个控件状态是固定不可变的时候 , 就可以使用 StatelessWidget 。前面我们写的 Hello World 就是使用 StatelessWidget 。
容器控件
容器类控件一般是将某些属性或配置 , 作用在它的子控件上 , 比如控件所在的宽高、背景、位置等 。
常用的容器控件有 Container、Center、Padding 等 。

秒懂生活扩展阅读