Flutter 是 Google 推出的 UI 框架,帮助开发者通过一套代码同时运行在 iOS 和 Android 上,构建媲美原生体验的精美应用!实际上 Flutter 不止于移动平台,正逐渐从移动设备扩展到多个平台,例如 Web、macOS、Windows、Linux、嵌入式设备等,因此 Flutter 是适用于所有屏幕的便携式界面框架,Flutter 一切皆是 Widget;自绘 UI;Flutter 只接管 UI 层,蓝牙等系统功能通过插件的形式提供。
开放:完全开源的项目 ( BSD 开源协议 )
Flutter 使用 C、C++、Dart 和 Skia ( 2D 渲染引擎 ) 构建,详情见 Flutter 系统架构
Flutter ( Android / iOS )Flutter Web
技术都是相通的,寻找相似点能让我们快速上手一门新技术。
Flutter 与前端有不少相似点,比如 Flutter 借鉴了 React 响应式 UI 编程的思想,Flutter 也有 Flexbox、Grid 布局,此外 Dart 与 JavaScript 的语法有不少相似点。
实际上,Flutter 项目正是诞生于 Chrome 团队,详情见 “听 Flutter 创始人 Eric 为你讲述 Flutter 的故事”。此外,Dart 设计之初是为了取代 JavaScript,只不过最终取代失败,因而转换定位,服务于 Flutter。
Flutter | 前端 | |
---|---|---|
编程语言 | Dart | JavaScript |
响应式 UI 编程 | 借鉴 React | React、Vue、Angular |
状态管理 | Provider、Redux、Mobx | Redux、Mobx、Vuex |
页面样式 | Widgets | CSS、styled-component |
UI 库 | 官方内置 Material Design、Cupertino | 社区 Ant Design、Element |
内嵌视图 | PlatformView | iframe |
开发和调试工具 | Dart DevTools | Chrome DevTools |
编辑器 | VS Code、Android Studio | VS Code、Sublime Text |
在线编辑器 | DartPad、CodePen | CodePen、JSFiddle |
包管理工具 | pub | npm、yarn |
Dart | JavaScript | |
---|---|---|
编译 | 即时编译 (JIT) 或提前编译 (AOT) | 即时编译 ( JIT ) |
异步非阻塞 | 单线程、事件循环、微任务、宏任务 | 单线程、事件循环、微任务、宏任务 |
异步编程 | Future、async、await | Promise、async、await |
类型系统 | type safestatic type checking and runtime checks | TypeScriptstatic type definitions |
继承 | Class | 原型链 |
密集型计算 | Isolate | Web Worker |
Flutter | CSS | |
---|---|---|
样式化文本 | Text、RichText | font-size、font-weight、font-family... |
盒模型 | 只有 border-box | box-sizing: content-box、border-box; |
弹性盒子布局 | Row、Column | display: flex、inline-flex;flex-direction: row、column; |
网格布局 | Grid | display: grid; |
定位方式 | Aligin、Stack & Positioned、Slivers | position: static、relative、absolute、sticky、fixed |
变换 ( 旋转 缩放 倾斜 平移等 ) | Transform | transform |
举个
Transform transform
// Flutter Dart
var container = Container( // grey box
color: Colors.grey[300],
width: 320,
height: 240,
child: Center(
child: Text(
"Lorem ipsum",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 24,
fontFamily: "Georgia",
),
),
),
);
2 . Dart 的运行时和编译器支持 Flutter 的两个关键特性
3 . Dart团队就在你身边:与 Dart 社区展开了密切合作,Dart 社区积极投入资源改进 Dart,以便在 Flutter 中更易使用
Flutter | Android、iOS | Hybrid | React Native、Weex |
---|---|---|---|
适用于不带 UI 的功能,Flutter 与原生约定通道方法,原生通过 API 的形式提供定位、蓝牙、传感器等系统功能,或者复用客户端 SDK,提供请求、上传、美颜、人脸识别、推送、 IM 等基础功能
适用于带 UI 的功能,Flutter 内嵌原生视图,例如地图、WebView 等
// Flutter Dart
var container = Container( // grey box
color: Colors.grey[300],
width: 320,
height: 240,
child: Center(
child: Text(
"Lorem ipsum",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 24,
fontFamily: "Georgia",
),
),
),
);
适用于带 UI 的功能,原生提供图像数据 ( 相机拍摄画面、视频播放帧 ),Flutter 通过 ID 引用原生存放于 GPU 的图像数据,然后自定义 UI,例如相机、相册、播放器等
Flutter 的 UI 代码使用 Dart 语言,其优点如下:
不需要维护代码之外的 UI 定义文件
但是,也存在几个问题:
问题一:复杂 UI 逻辑会使用命令式语法,打破代码结构和 UI 视觉结构的一致性 ( 代码看起来更像是命令式的而不是声明式的 )
image.png
Widget build(BuildContext context) {
List<SegmentedTabBarItem> items = [];
List genders = ["男生", "女生", "不限"];
for (int i = 0; i < genders.length; i++) {
items.add(SegmentedTabBarItem(
text: genders[i],
width: 102,
radius: 8,
fontWeight: FontWeight.w500,
selectedTextColor: Colors.white,
duration: Duration(milliseconds: 0),
));
}
return SegmentedTabBar(
tabItemSpacing: 6.5,
tabBarRadius: $rem(12),
tabIndex: genderIndex,
padding: EdgeInsets.symmetric(horizontal: 0),
selectedItemBackgroundColor: Colors.purple,
duration: Duration(milliseconds: 0),
children: items,
onSelected: (int index) {
setState(() {
genderIndex = index;
});
},
);
}
SegmentedTabBar 在概念和视觉上都应该先于 items 出现。但是由于语法局限,这个空间关系被反了过来。代码看起来更像是命令式而不是声明式。
解决方案:在 Dart 2.3 中加入了针对 UI 编程优化的新语法元素,即可以在集合数据类型的定义中使用 if 和 for 这样的流程控制元素。
Widget build(BuildContext context) {
return SegmentedTabBar(
tabItemSpacing: 6.5,
tabBarRadius: $rem(12),
tabIndex: genderIndex,
padding: EdgeInsets.symmetric(horizontal: 0),
selectedItemBackgroundColor: Colors.purple,
duration: Duration(milliseconds: 0),
children: <SegmentedTabBarItem>[
for (String label in ["男生", "女生", "不限"])
SegmentedTabBarItem(
text: label,
width: 102,
radius: 8,
fontWeight: FontWeight.w500,
selectedTextColor: Colors.white,
duration: Duration(milliseconds: 0),
),
],
onSelected: (int index) {
setState(() {
genderIndex = index;
});
},
);
}
问题二:多层嵌套之后不容易对 UI 的构成做到一目了然
解决方案:IDE 中加入了 Editor UI Guides
image.png
Demo 演示
扫一扫
在手机上阅读