带你深入理解不一样的 Flutter

作者:GSYTech@微信公众号 搜狐技术产品
出处:
本文字数: 2608 字
预计阅读时间: 6 分钟
本文主要介绍 Flutter 的现状和 Widget 的灵魂设计 , 用不一样的角度带你领略 Flutter 的魅力所在 , 相信本篇文章会给你带来 Flutter 上不一样的理解 。
一、Flutter 的现状Flutter 作为谷歌的新一代跨平台技术方案 , 它使用 自带的绘制引擎, 优雅地解决了以前跨平台开发上 兼容 和 性能 的痛点 , 通过成熟的 Skia 引擎去实现控件的绘制 , 让控件与平台 解耦, 在提高性能的同时也增强了代码在不同平台的 复用率。
Flutter 如今在国内如:字节跳动、阿里巴巴、腾讯、京东、网易、美团等企业都相继投入使用 , 甚至阿里巴巴已经成立了 Alibabab-Flutter 相关事业组用于集团开发维护 , 今年 Alibabab-Flutter 更是战略上升到集团移动委员会四大战略之一 , 得到了资源上的重点投入 , 由多 BU 合作共建 。
从实际使用角度出发 , Flutter 如今已经在各大企业的产品投入使用 , 在 《国内大厂在移动端跨平台的框架接入分析》 中分析了 52 款大厂应用 , 其中就有 19 款应用集成了 Flutter 的开发能力 。
Flutter 最大的特点就在于它的渲染引擎 , Flutter 中提供的控件和 Canvas 能力都是通过 Flutter Engine 实现 。
不同于 ReactNative 通过转化为原生控件再去渲染 , Flutter Engine 在 Android 和 iOS 平台只需要提供对应的 Surface, 剩下都由 Flutter Engine 来完成绘制 , 这大大降低了 Flutter 和平台的耦合度 , 同时也让渲染出来的控件在不同平台能有一致性的表现 。
带你深入理解不一样的 Flutter文章插图
Flutter 如今除了 Android 和 iOS 平台之外 , 对于 Web 、 MacOS 、 Linux 平台的支持也进入了 beta 阶段 ,Win 进入了 PreView 阶段 , 这也是得益于 Flutter 优秀的底层设计 。
而对于 Flutter, 相信开发者们最常用也最熟悉的就是 Widget, 而 Widget 的设计理念也正是它的灵魂所在 。
二、Widget , Flutter 中一切的开始要理解 Flutter 就要理解 Flutter 中最灵魂的设计:
Flutter 内一切皆 Widget,Widget 是不可变的(immutable) , 每个 Widget 状态都代表了一帧 。
理解这段话是非常重要的 , 因为 Flutter 中所有界面的展示效果 , 在代码层面都是通过 Widget 作为入口开始 。Widget 是不可变的 , 说明页面发生变化时 Widget 一定是被重新构建 , 所以 Widget 的固定状态代表了一帧静止的画面 , 当画面发生改变时 , 对应的 Widget 一定会变化 。
举个例子 , 如下代码所示定义了一个 TestWidget,TestWidget 接受传入的 title 和 count 参数显示到 Text 上 , 同时如果 count 大于 99 , 则只显示 99 。
Warnning/// This class is marked as '@immutable'/// but one or more of its instance fields are not finalclass TestWidget extends StatelessWidget {final String title;int count;TestWidget({this.title, this.count});@overrideWidget build(BuildContext context) {this.count = (count > 99) ? 99 : count;return Container(child: new Text("$title $count"),);}}这段代码看起来没有什么问题 , 也可以正常运行 , 但是在编译器上会有 “This class is marked as '@immutable' , but one or more of its instance fields are not final” 的提示警告 , 这是因为 TestWidget 内的 count 成员变量没有加上 final 声明 , 从而在代码层面容易产生歧义 。
因为前面说过 Widget 是 immutable, 所以它的每次变化都会导致自身被重新构建 , 也就是 TestWidget 内的 count 成员变量其实是不会被保存且二次使用 。
如上所示代码中 count 成员没有 final 声明 , 所以理论是可以对 count 进行二次修改赋值 , 造成 count 成员好像被保存在 TestWidget 中被二次使用的错觉 , 容易产生歧义 。
那这时候可能有人会问: 每次 Widget 都重构 , 那怎么保存状态?这样 Widget 的设计会不会性能很差?
三、Element , Flutter 的背后大佬前面说过 ,Flutter 中的 Widget 是不可变的 , 比如前面用的 StatelessWidget, 一个 Widget 状态代表了一帧 , 而在 Flutter 里提供了 StatefulWidget 实现跨帧保存状态的功能 。
那什么是 StatefulWidget ?如下代码所示 , 只需要让 TestWidget 继承 StatefulWidget, 然后将 build 方法和 count 写到 State 内 , 就可以实现 count 状态的跨帧保存 。
当然这里的 title 参数还是定义在 Widget 层面 , 所以依旧需要 final。
class TestWidget extends StatefulWidget {final String title;TestWidget({this.title});@override_TestWidgetState createState() => _TestWidgetState();}class _TestWidgetState extends State {int count;@overrideWidget build(BuildContext context) {this.count = (count > 99) ? 99 : count;return InkWell(onTap: () {setState(() {count++;});},child: Container(child: new Text("${widget.title} $count"),),);}}