今天给大家介绍的是Dart2和Flutter
Dart是google推出的一种新的脚本语言, 希望能替代JS,
然而JS也在迭代升级, 生命力很旺盛,
目前, Dart还没能替代JS.
现在最新的Dart是2, 据说相比1改变很多.
所以我直接介绍dart2.
Flutter是google推出的跨平台开发框架, 类似于React-native.
不过相比于React-native, 它的性能更有优势.
1. 下载Flutter SDK, 解压到C盘.
是一个zip包, 解压到C盘, 因为担心权限问题, 要求不要放到program Files.
https://flutter.io/sdk-archive/#windows
2. 将c:/flutter/bin添加到环境变量path
3. 添加两个环境变量的添加是为避免国内访问不到有些地址,
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
4. 升级和检查
flutter doctor
flutter upgrade
5. 设置编辑器
vscode Extensions: Install Flutter
6. android studio安装
7. android studio安装flutter插件
8. android studio配置虚拟安卓设备.
Dart类似于JS, 可以应用于web, server等应用场景, 在flutter框架下也支持了移动端开发.
1. 需要main入口才能运行.
2. Raw字符串, 不会发生转义
3. 多行字符串, 考虑到代码上加的空格也会体现出来, 所以如果用这种方法, 又不想要这些空格, 会破坏代码的整体美观.
4. 字符串中嵌入变量, 相比JS有些简化
5. Future相比Promise简便一点. 并且它可以加一个Duration来完成timeout的工作.
6. async/wait可以应用场景可以更自由. 比如for循环
还有一些没在这里演示, 比如类型继承, class extend, 类型安全等跟ts就比较像了.
最大的优点是具备JS的大部分优点, 所以容易上手. 又去掉了JS的大部分缺点, 比如隐式转换.
1. 创建Flutter工程
vscode命令也可以, 在命令行中输入flutter new, 填入名字, 和angular-cli类似, 就能生产一堆代码.
2. Vscode打开工程, 左侧可以看到android, ios各自产生的相应的工程, lib/main.dart就是业务层代码了.
其它的大部分可以不用管, 不过这里有一个pubspec.yaml是一个包管理文件, 类似与package.json.
3. 找到lib/main.dart
写上这些代码
4. F5运行, 选择虚拟设备, 将会看到虚拟设备显示出实现的界面. (调试支持热重载)
这个例子中, 首先是main()的入口 调用 runApp创建app对象运行起来.
App对象从statelessWidget创建. 所谓statelesswidget就是属性不可变的widget意思.
而widget是所有控件的基类.
Widget最基本的方法就是build和setState
类似于React的render.
这里@override表示extend出来的子对象覆盖widget的build方法.
在flutter里绝大部分的可见或不可见的界面元素都是widget, 整个页面, 路由的页面, 容器, 行, 列, 甚至是padding.
MaterialApp是material组件之一, 提供整体的属性的定义.
比如整体的风格, 颜色, 名称,
Scaffold提供默认的导航栏, 标题, body等属性的定义.
Appbar标题栏
Text控件
Center是一个布局控件, 可以把子对象摆在中间, 像有图所示.
这里的名称加冒号的传参方式, 前面解释了,
是可选参的传递方式,不限定传参顺序.
这个例子要演示的是StateFulWidget和StateLessWidget的不同.
这里引入了一个能产生随机单词的外部包.
这里的外部包引用只需要在yaml填入包名称和版本号,
然后触发flutter: get package命令就会完成包引用和更新.
这里需要注意的是, 缩进的多少会影响语义.
这里可以看到, StatefulWidget是override createState 函数
返回一个new 的对象state<RamdomWords>模板参数又引用了前面这个类型,
这个写法有点奇怪, 有一种循环引用的错觉. 不过实际上并不是循环引用.
然后再在这个state<>又override 一个build方法.
当state有变化时, 会触发build, 也可以手动触发.
这里里面放入一个listView 和listTile构成一个列表.
每次滚动到底部, 都会触发itemBuilder传入新的i.
到了这里我们对Flutter和Dart就有了一个初步的了解了.
接下来看一下Flutter的架构.
Route在flutter中通过navigator来管理.
支持两种方式来做路由, 一种是stack push pop,
另一种就是常见的路径和页面映射.
这里演示的是第一种, 因为手机最常见的情况是跳转, 然后返回.
navigtor的push, pop, 操作widget对象来完成页面的跳转.
这种widget叫做MaterialPageRoute.
这里有一个navigator的例子, 实现的效果, 就是
点击右上角的按钮之后, 跳转到收藏页面,
点击返回又可以回到主页面.
代码实现是在右上角增加一个按钮的onPress事件触发
这个navigator.of是从当前的context也就是这个materialApp的navigator.
然后push一个MaterialPageRoute
Builder方法里返回一个Scofold页面就行了.
这里可以看到context包含app的环境信息或对象
MaterialApp的的routes属性可以设置路由路径和页面之间的映射关系.
new MaterialApp(
routes: {
'/a': (BuildContext context) => new MyPage(title: 'page A'),
'/b': (BuildContext context) => new MyPage(title: 'page B'),
}
除此以外, route还可以嵌套, 也就是说, app这一层是根路由,
而根路由里面的page还可以嵌入子路由, navigator.of访问context会
按照就近原则获取当前的路由进行操作.
官方的图标库集成了内部的接口, 方便直接加载, 基于矢量. 操作便捷, Icons.xxx就可以加载这个图标.
这里是对布局的演示,
Flutter的布局有一个特点, 就是它不用负责告诉它的父节点, 自己要显示在哪里.
主要是每种容器通过row, colum, list, card, gridview等容器来管着子节点的显示,
然后再容器的属性可配置主轴, 纵轴的对齐方式, padding, margin, border等.
children或child嵌入子节点. 理解起来还是比较简单的.
另外, 对于全局的风格, 在materialApp中也有属性进行定义.
Animation:
1. 按时间阶段输出.value
2. 监听状态(forward, backward, completed, dismissed)
AnimationController:
1. .forward, .backward控制向前向后
2. 设置变化的时长
CurvedAnimation:
1. 曲线变化(fastOutSlowIn, bounceIn, elasticInOut, 可自定义)
2. 将AnimationController和Curves组合出一个Animation对象
Tween(Animatable):
1. 设置Animation值变化范围
2. .evaluate(Animation)通过Animation可计算当前值
3. .animate(AnimationController)可以返回一个Animation
Pubspec.yaml文件, 配置包,类似于node.js的package.json文件.
前面提到配置的包在这里有修改的话,
会可以自动触发更新
相比npm install在编写代码再去输入命令要更便捷一点.
命令也支持.
然而这个国外的源可能被封禁, 所以经常get失败,
谷歌说提供了一个国内的源, 但是实际使用的时候, 发现效果也是很差.
另外还可以配置图片, 自定义字体, 本地语言等.
大多数控件有onPress事件, 但是手机上的手势行为很多
因此并没有让每一个控件支持所有手势的属性,
所以如果想要获得哪些手势就需要使用GetureDetector
而GetureDetector本身也是一种widget把它和其它控件重叠放在一起,
或者把其它控件作为GetureDetector的子控件.
它就可以检测到这个控件上发生的手势动作.
这里列举了可支持的手势动作.
调试上除了传统的断点单步调试, 也一样支持inspector和性能分析
不过提供的inspector支持不在vscode上., 而是intelliJ,
可以查看节点层次和节点属性, 只不过不能直接在inspetor里面修改属性.
android studio是基于intelliJ的IDE, 所以也是支持的.
每个API都有一个独立的路径, 获得路径对应的methodchannel对象
然后通过.invokeMethod(funcName)来访问接口.
这里为防止阻塞使用了async await.
已有的这些访问API的路径包含…
如果开发发现还不够, 可以自己在native开发这一层
添加自定义的API路径和native api之间的映射.
而数据的返回有两种形式, 一种从result.success, result.error阻塞式返回.
另一种是通过event.
Flutter的框架从上到下分三个大层:
FrameWork主要包含UI组件(Material和Cupertino widgets)也包含:
widgets, Animation, getstures等
Engine主要是指Dart的引擎, 还包括
Event, pipeline, 服务协议, 渲染等.
Embedder主要是native层的一些接口和线程, 事件, 包管理等.
根据介绍Flutter相比React最大的优势在于,
在上层就完成了render, 避免了diff变化的层层传递. 所以性能更好.
打包和发布, 在各自的平台有一些不同的操作流程.