Flutter的学习 1/16
前言
Flutter 是 Google推出并开源的移动应用开发框架,通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter提供了丰富的组件、接口,开发者可以很快地为 Flutter添加 native扩展。同时 Flutter还使用 Native引擎渲染视图,能为用户提供良好的体验。
- 原生性能:使用Native引擎渲染。
- 支持HotLoad快速开发,UI代码及时生效。
- 访问本地功能和SDK:Flutter可以复用现有的Java、Swift或ObjC代码,访问iOS和Android上的原生系统功能和系统SDK。所以理应也可以单独实现某个模块。
绘图基本原理
屏幕显示图像的基本原理是显示器以固定的频率刷新,比如 iPhone的 60Hz、iPad Pro的 120Hz。当一帧图像绘制完毕后准备绘制下一帧时,显示器会发出一个垂直同步信号(VSync),所以 60Hz的屏幕就会一秒内发出 60次这样的信号。
并且一般地来说,计算机系统中,CPU、GPU和显示器以一种特定的方式协作:CPU将计算好的显示内容提交给 GPU,GPU渲染后放入帧缓冲区,然后视频控制器按照 VSync信号从帧缓冲区取帧数据传递给显示器显示。
所以,Android、iOS的 App在显示 UI时是如此,Flutter也不例外,也遵循了这种模式。所以从这里可以看出 Flutter和 React-Native之众的本质区别:React-Native之类只是扩展调用 OEM组件,而 Flutter是自己渲染。
在 Flutter Architecture的解释中,Google还提供了一张更为详尽的图来解释 Flutter的原理
Skia是一个 2D的绘图引擎库,Chrome和 Android均采用 Skia作为绘图引擎
Dart 的性能
Dart 的性能更好。Dart在 JIT模式下,速度与 JavaScript基本持平。但是 Dart支持 AOT,当以 AOT模式运行时,JavaScript便远远追不上了。速度的提升对高帧率下的视图数据计算很有帮助。
AOT
技术随着时间之轮毫不停歇前行。Android kitkat 4.4,新的Android Runtime(ART)出现了,做为一个可选项,供一些愿意的用户测试使用,当然这个时候Dalvik还是作为默认的虚拟机环境。ART采取了AOT(Ahead-Of-Time)技术,简单一点理解就是,在APK安装的时候就会做预先编译动作,编译好的文件是OAT文件,该文件本质上是一个ELF文件,这里与dex(Odex)文件最大的区别是OAT文件不再是字节码文件,而是一个可执行文件,可以更底层的与硬件接触,运行时也省去了预编译和转译的时间。
Flutter Widget
在 Flutter 中,一切的显示都是 Widget 。Widget 是一切的基础,作为响应式的渲染,属于 MVVM 的实现机制。我们可以通过修改数据,再用setState 设置数据,Flutter 会自动通过绑定的数据更新 Widget 。所以你需要做的就是实现 Widget 界面,并且和数据绑定起来。
Widget 分为 有状态 和 无状态 两种,在 Flutter 中每个页面都是一帧。无状态就是保持在那一帧。而有状态的 Widget 当数据更新时,其实是绘制了新的 Widget,只是 State 实现了跨帧的数据同步保存。
无状态StatelessWidget
继承 StatelessWidget,通过 build 方法返回一个布局好的控件,静态。
Widget 和 Widget 之间通过 child:
进行嵌套。其中有的 Widget 只能有一个 child,比如下方的 Container
;有的 Widget 可以多个 child ,也就是children:
。下方代码便是 Container Widget 嵌套了 Text Widget。
import 'package:flutter/material.dart';
class LessDemo extends StatelessWidget {
final String text;
//数据可以通过构造方法传递进来
LessDemo(this.text);
@override
Widget build(BuildContext context) {
//这里返回你需要的控件
//这里末尾有没有的逗号,对于格式化代码而已是不一样的。
return Container(
//白色背景
color: Colors.white,
//Dart语法中,?? 表示如果text为空,就返回尾号后的内容。
child: Text(text ?? "这就是无状态DMEO"),
);
}
}
有状态StatefulWidget
你需要创建管理的是主要是 State
, 通过 State 的 build
方法去构建控件。在 State 中,你可以动态改变数据,这类似 MVVM 实现,在 setState
之后,改变的数据会触发 Widget 重新构建刷新。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or press Run > Flutter Hot Reload in IntelliJ). Notice that the
// counter didn't reset back to zero; the application is not restarted.
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
//
_counter++;
});
}
@override
Widget build(BuildContext context) {
//Scaffold是官方的 UI 框架,这个框架包含 头部导航栏,body,右下角浮动按钮,底部导航栏等
return new Scaffold(
appBar: new AppBar(
//注意,这里title是 Widget 类型
title: new Text(widget.title),
),
//Scaffold 的下一个参数就是 body 了,用来展示 APP 的主体部分。主体部分大部分是通过组合 Container ,Column,Row,Stack来实现的
body: new Center( //子 Widget ,居中显示,用于嵌套child,设置child居中
// in the middle of the parent.
child: new Column( //可以有多个子widget,垂直布局
// Column is also layout widget. It takes a list of children and
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
//floatingActionButton是 Scaffold 一个参数,这个参数用来定义浮动在 body 右下角的组件
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Scaffold
,官方的 UI 框架,这个框架包含 头部导航栏,body,右下角浮动按钮,底部导航栏等[^]title
是 Widget 类型,例:
final Widget title; //大概这样写
body
Scaffold 的下一个参数就是 body 了,用来展示 APP 的主体部分。主体部分大部分是通过组合 Container ,Column,Row,Stack来实现的Center
子Widget ,居中显示,用于嵌套child,设置child居中Column
子Widget,可以有多个子widget,垂直布局floatingActionButton
是 Scaffold 一个参数,这个参数用来定义浮动在 body 右下角的组件
参考链接 :
https://mp.weixin.qq.com/s/8OKI-gNu4Qrt298zae43SQ
https://juejin.im/post/5afd77466fb9a07aab2a12da
https://mp.weixin.qq.com/s/CQQXD0TrlbaNWjoClIcDtw
https://zhuanlan.zhihu.com/p/41595954
https://www.jianshu.com/p/ac079e7fc412
https://flutter-io.cn/