flutter也已经出来很久了, 现在也推出了打包到桌面端的版本, 感觉生态以及完善了. 本来早就立下目标打算接触一下的, 但是懒癌发作, Rn看了几眼就没有结果了, 现在也到了不得不提升自己的时候了
搭建Flutter开发环境
来自Google的东西再国内使用开发环境配置都挺麻烦的, 特别是Flutter编译到Android平台必须配置原生APP的开发环境
下载SDK, 配置环境变量
直接去官网就可以下载
https://flutter.cn/development/tools/sdk/releases
然后解压到任意位置, 注意目录中不能用空格, 最好也别放C盘Program Files
目录下, 它不仅有空格, 还有特殊权限
打开解压放置的flutter
SDK文件夹, 打开bin
文件夹, 复制当前目录地址, 转到 “控制面板>用户帐户>用户帐户>更改我的环境变量”, 再Path
变量下把复制的地址新增上去
运行 flutter doctor命令
在Flutter命令行运行如下命令来查看是否还需要安装其他依赖,如果需要,安装它们:
1 | flutter doctor |
该命令检查你的环境并在命令行窗口中显示报告。Dart SDK已经在打包在Flutter SDK里了,没有必要单独安装Dart。 仔细检查命令行输出以获取可能需要安装的其他软件或进一步需要执行的任务。
例如:
1 | [-] Android toolchain - develop for Android devices |
第一次运行flutter命令(如flutter doctor)时,它会下载它自己的依赖项并自行编译。以后再运行就会快得多。缺失的依赖需要安装一下,安装完成后再运行flutter doctor命令来验证是否安装成功。
Dart 语言简单入门
变量声明
Dart是一个强类型语言, 但是声明变量可以自动推断类型
1 | var t = "hi wold"; |
Object 是 Dart 所有对象的根基类,也就是说在 Dart 中所有类型都是Object的子类(包括Function和Null),所以任何类型的数据都可以赋值给Object声明的对象。 dynamic与Object声明的变量都可以赋值任意对象,且后期可以改变赋值的类型,这和 var 是不同的,如:
1 | dynamic t; |
dynamic与Object不同的是dynamic声明的对象编译器会提供所有可能的组合,而Object声明的对象只能使用 Object 的属性与方法, 否则编译器会报错,如:
1 | dynamic a; |
dynamic 的这个特点使得我们在使用它时需要格外注意,这很容易引入一个运行时错误,比如下面代码在编译时不会报错,而在运行时会报错:
1 | print(a.xx); // a是字符串,没有"xx"属性,编译时不会报错,运行时会报错 |
如果您从未打算更改一个变量,那么使用 final 或 const,不是var,也不是一个类型。 一个 final 变量只能被设置一次,两者区别在于:const 变量是一个编译时常量(编译时直接替换为常量值),final变量在第一次使用时被初始化。
函数
art是一种真正的面向对象的语言,所以即使是函数也是对象,并且有一个类型Function。这意味着函数可以赋值给变量或作为参数传递给其他函数,这是函数式编程的典型特征。
1 | bool isNoble(int atomicNumber) { |
Dart函数声明如果没有显式声明返回值类型时会默认当做dynamic处理,注意,函数返回值没有类型推断
1 | // 对于只包含一个表达式的函数,可以使用简写语法: |
包装一组函数参数,用[]标记为可选的位置参数,并放在参数列表的最后面:
1 | String say(String from, String msg, [String? device]) { |
定义函数时,使用{param1, param2, …},放在参数列表的最后面,用于指定命名参数。例如:
1 | //设置[bold]和[hidden]标志 |
可选命名参数在Flutter中使用非常多。注意,不能同时使用可选的位置参数和可选的命名参数。
异步支持
Dart类库有非常多的返回Future
或者Stream
对象的函数。 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作。而不是等到这个操作完成。
async
和await
关键词支持了异步编程,允许您写出和同步代码很像的异步代码。
Future
与JavaScript中的Promise非常相似,表示一个异步操作的最终完成(或失败)及其结果值的表示。简单来说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。一个Future只会对应一个结果,要么成功,要么失败。Future 的所有API的返回值仍然是一个Future对象,所以可以很方便的进行链式调用。
1 | Future.delayed(Duration(seconds: 2),(){ |
Future.wait
用法与Promise.all
一致, Dart中的async/awai
t 和JavaScript中的async/await
功能是一样的
Stream
也是用于接收异步事件数据,和 Future
不同的是,它可以接收多个异步操作的结果(成功或失败)。 也就是说,在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。 Stream
常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等。举个例子:
1 | Stream.fromFutures([ |
上面的代码依次会输出:
1 | I/flutter (17666): hello 1 |
代码很简单,就不赘述了。