1.目标
- 对flutter有个整体性的认知,知道是什么,有什么优缺点,有哪些需要掌握的新技能点**——**dart语言
- 简单的开发demo**——**电子书文档
- 前提:
- 已完成本地环境的配置,初始化demo的实现
- 医生端doctor-flutter代码可进行学习
- 弄清楚doctor-dns中怎么引入doctor-flutter中的代码的**——**通过二方库方式进行导入,FlutterFragment进行使用。
2.学习记录
1.整体概述
是什么?
是谷歌的移动UI框架,快速构建android和ios的原生用户界面,跨端开发。
- 快速开发:支持热重载,修改后立即更新,类似前端开发的页面更新速度
- 包含很多核心的widget,如滚动、导航、字体,可直接使用,在android和ios上的与原生一样的性能
- 分层架构,允许自定义,实现灵活设计。
- 响应式框架,同基础widget一起,能轻松构建界面。
- 能复用现有的Java、swift或者objc的代码,访问原生功能和系统sdk
- 在Android和iOS上实现统一的应用开发体验,使用native引擎渲染试图,提供好的用户体验
优点:
- 跨平台自绘引擎,Skia为其2D渲染引擎。支持Android、iOS、Fuchsia(google新的自研操作系统),支持web开发(flutter for web)和PC。
- 高性能
- 使用dart语言进行开发
- 即时编译(JIT)模式,速度与JavaScript持平。
- 支持提前编译(AOT)
- 使用自己的渲染引擎绘制UI,布局由dart语言直接控制,在布局过程中不需要像RN那样在JavaScript和native之间通信,减少了性能开销。
- 使用dart语言进行开发
需要的新技能点:
dart语言
dart语言的优点:
- 开发效率高
- 开发阶段JIT,避免每次改动都要进行编译,极大节省开发时间;
- 发布阶段AOT,生成高效的ARM代码
- 高性能-AOT
- 快速内存分配,类型安全语言,支持静态类型检测。而Java是弱类型语言
- 团队投入
框架结构:
Flutter是纯Dart实现的sdk,实现了一套基础库。自下而上,
-
Flutter底下的两层(Animation、Painting、Gestures、Foundation)也被描述为dart UI层,对应dart:Ui包,是底层库,提供动画、手势、绘制能力
-
Rendering层,是一个抽象布局层。会构建一个UI树,当树上有变化的时候,会计算出变化的部分,更新UI树,然后绘制到屏幕上,类似于React中的虚拟DOM。
Rendering是Flutter UI框架的核心部分,确定了每个UI元素的位置、大小、坐标变换、绘制(底层实现)。
-
Widgets层,是Flutter提供的一套基础组件库,在此之上,还提供了Material和Cupertino两种视觉风格的组件库。Flutter开发中的大多数场景,只跟这两个层打交道。
在Flutter中,widget由其底层的RenderBox对象渲染。 渲染框由它们的父级给出约束,并且在这些约束下调整自身大小。约束由最小宽度、最大宽度和高度组成; 尺寸由特定的宽度和高度组成。
Flutter Engine
是纯C++ 的SDK,实现真正的绘制逻辑。
2.Dart简介
1.变量声明
var: 可以接收任何声明的变量,但是一旦被赋值后,类型就确定了,不会改变。
dynamic和Object:
- Object是Dart所有对象的根基类,dynamic和object都可以在变量声明后改变赋值类型。
- dynamic修饰的对象编译器会提供所有可能的组合,而object声明的对象只能使用object的属性和方法,否则编译器会报错。
final和const: 声明常量。final变量只能设置一次,const常量是编译时常量。被两者修饰的变量的类型可以省略。
2.函数
Dart是面向对象的语言,函数也是对象,且有一个类型Function。函数可以作为变量或者参数传递给其他函数,是**函数式编程**。
函数如果没有显示声明,返回的类型默认为dynamic,没有类型的推断。
可选位置参数: 包装一组函数参数,用[]标记为可选位置参数,并放在参数列表的最后面。示例:
String say(String from, String msg, [String device]){
var result = '$from says $msg';
if(device != null){
result = '$result with a $device';
}
return result;
}
say('Bob', 'Hello');//Bob says Hello
say('Bob', 'Hello', 'smoke signal';)//Bob says Hello with smoke signal
可选的命名函数:定义函数时{param1, param2,…}放在参数列表的最后面,用于指定命名参数。
void enableFlags({bool bold, bool hidden}){
//...
}
//调用函数
enableFlags(bold:true, hidden:false);
不能同时使用可选的位置参数和可选的命名参数。
3.异步支持
返回Future和Stream对象的函数,为异步函数。
async和await关键词支持异步编程。
Future
与Javascript中的Promise相似,表示一个异步操作的最终完成(或失败)及其结果值的表示。一个Future只会对应一个结果,要么成功,要么失败。
Future.delayed(new Duration(seconds:2),(){
throw AssertionError("Error");
}).then((data){
//成功
print("success");
}).catchError((e){
//失败
print(e);
}).whenComplete((){
//无论成功或在失败都会走到这里
});
当需要等待多个异步任务都执行结束才能进行一些操作,使用Future.wait。
Future.wait([
Future.delayed(new Duration(seconds : 2),(){
return "hello";
},
Future.delayed(new Duration(seconds : 3),(){
returen " world";
})
]).then((results){
print(results[0] + results[1]);
}).catchError((e){
print(e);
});
async和await的使用与JavaScript中一样。
Stream
与Future的不同在于,它可以接收到多个异步操作的结果,可以通过多次触发成功或失败时间来传递结果或者异常。Stream常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等。
Stream.fromFutures([
Futrue.delayed(new Duration(seconds:1),(){
return "hello 1";
}),
Futrue.delayed(new Duration(seconds:2,(){
throw AssertionError("Error");
}),
Futrue.delayed(new Duration(seconds:3),(){
return "hello 3";
})
]).listen((data){
print(data);
}, onError: (e){
print(e.message);
}, onDone:(){
});
//会输出
hello 1
Error
hello 3
3.疑问点
无
4.总结
通过阅读的实战电子书,这一文档,对目标中所列出的疑问点得到了解决。