vlambda博客
学习文章列表

【活动回顾】Flutter 跨平台UI框架

编辑:尤逸昊

排版:赵海蒙


周末刚刚结束的 Flutter Party 大家有没有来呢?当天天气不好,但是依然抵挡不住各位小伙伴的热情,冒雨前来参加 GDG 的活动,着实要为每位坚持前来的小伙伴点个赞呢!

当天美味的茶歇以及精彩的分享,不知道有没有满足各位呢?如果没有满足,在这里GDG 再给大家准备一份惊喜大礼包哈!👇👇👇

总长超过23小时的1080p视频教程,通过开发15个完整的app来让你快速成为一个flutter大佬!

(点击文末链接即可视频教程页面)

本期文章留言评论点赞数最多的十个人将有机会获得惊喜大礼包一份哦~

本期文章留言评论点赞数最多的十个人将有机会获得惊喜大礼包一份哦~

本期文章留言评论点赞数最多的十个人将有机会获得惊喜大礼包一份哦~

part 1—Flutter的特点

Flutter 与 Cordova、React Native 相比,具有许多独特的实现,以下是它众多特点中最有特色的3项:

•平台提供 Surface 和 Canvas

•UI 控件和平台无关

•使用 Dart 而非 Javascript

Flutter 与其它大多数框架不同,因为 Flutter 既不使用 WebView(如 Cordova),也不使用操作系统的原生控件(如 RN),而是使用自己的高性能渲染引擎来绘制Widget(后续会进一步介绍什么是Widget)。这样可以保证在多平台上 UI 的一致性,也可以打破对原生控件依赖而带来的限制。

Flutter 所使用的 Dart 语言支持 AOT,在 AOT 下速度远超 JS。同时,Flutter 使用自己的渲染引擎来绘制 UI,布局数据等由 Dart 语言直接控制,所以在布局过程中不需要像 RN 那样要在 JavaScript 和 Native 之间通信,可以减少性能开销。

【活动回顾】Flutter 跨平台UI框架

【活动回顾】Flutter 跨平台UI框架part 2—Flutter Widget

在 Flutter 中,Widget的功能是“描述一个 UI 元素的配置数据”,Flutter 内一切皆Widget,而Widget本身是不可变的,没个Widget状态都代表了一帧。

Widget是怎么工作的呢?

Widget其实并不是表示最终绘制在设备屏幕上的显示元素,而它只是描述显示元素的一个配置数据。

实际上,Flutter 中真正代表屏幕上显示元素的类是Element,也就是说Widget只是描述Element的配置数据。Widget只是 UI 元素的一个配置数据,并且一个Widget可以对应多个Element,这是因为同一个Widget对象可以被添加到UI树的不同部分,而真正渲染时,UI树的每一个Element节点都会对应一个Widget对象。

【活动回顾】Flutter 跨平台UI框架

以下是一个简单的Stateless Widget示例:

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: const Text('Welcome to Flutter'), ), body: const Center( child: const Text('Hello World'), ), ), ); }}

这里的BuildContext 就是Widget对应的Element,我们可以通过context去获取Element里的东西,比如StateRenderObject

Widget有很多类别,接下来我们进一步展开。

【活动回顾】Flutter 跨平台UI框架part 2.1—StatelessWidget

在上面的示例中,我们已经看到了StatelessWidgetStatelessWidget相对比较简单,它继承自Widget类,重写了createElement()方法:

@overrideStatelessElement createElement() => new StatelessElement(this);

StatelessElement 间接继承自Element类,与StatelessWidget相对应(作为其配置数据)。StatelessWidget用于不需要维护状态的场景,它通常在build方法中通过嵌套其它Widget来构建UI,在构建过程中会递归的构建其嵌套的Widget

【活动回顾】Flutter 跨平台UI框架part 2.2—StatefulWidget

StatelessWidget一样,StatefulWidget也是继承自Widget类,并重写了createElement()方法,不同的是返回的Element 对象并不相同;另外StatefulWidget类中添加了一个新的接口createState()

abstract class StatefulWidget extends Widget { const StatefulWidget({ Key key }) : super(key: key);
@override StatefulElement createElement() => new StatefulElement(this);
@protected State createState();}

StatefulElement 间接继承自ElementStatefulWidget相对应(作为其配置数据)StatefulElement中可能会多次调用createState()来创建状态(State)对象。

createState() 用于创建和StatefulWidget相关的状态,它在StatefulWidget的生命周期中可能会被多次调用,本质上就是一个StatefulElement对应一个 State 实例。

【活动回顾】Flutter 跨平台UI框架part 2.3—State

一个 StatefulWidget 类会对应一个 State 类,State 表示与其对应的 StatefulWidget 要维护的状态。

State 保存在了 Element ,实现跨帧共享状态。

这里附上一个StatefulWidget的示例,实现的是一个计数器:

class CounterWidget extends StatefulWidget { const CounterWidget({ Key key, this.initValue: 0 });
final int initValue;
@override _CounterWidgetState createState() => new _CounterWidgetState();}

class _CounterWidgetState extends State<CounterWidget> { int _counter;
@override Widget build(BuildContext context) { print("build"); return Scaffold( body: Center( child: FlatButton( child: Text('$_counter'), //click and count onPressed:()=>setState(()=> ++_counter, ), ), ), ); }}

【活动回顾】Flutter 跨平台UI框架part 2.4—容器Widget和渲染Widget

TextSliderListTile等都属于渲染Widget,其内部主要是RenderObjectElement

StatelessWidgetStatefulWidget等属于容器Widget,其内部使用的是ComponentElement,本身是不存在RenderObject的。

获取Widget的位置和大小等,都需要通过RenderObject获取。

part 3—RendorObject

最后我们来简单介绍一下刚刚提到过几次的RendorObject

RenderObject就是渲染树中的一个对象,每个Element都对应一个RenderObject,我们可以通过Element.renderObject 来获取。并且我们也说过RenderObject的主要职责是 Layout 和绘制,所有的RenderObject会组成一棵渲染树 Render Tree。

RendorObject颗粒度很细,功能很单一,负责 layout 和 paint 的过程。大部分 Widget 的绘制对象会是子类 RenderBox(RenderSliver 例外)。

理解RenderObject主要的功能和方法可以帮助我们更好地理解 Flutter UI 的底层原理,但这一部分较为复杂,限于篇幅原因这里就不再深入阐述了,各位读者可以通过官方文档进行进一步学习。


关于GDG

Google Developer Groups 谷歌开发者社区,是谷歌开发者部门发起的全球项目,面向对 Google 和开源技术感兴趣的人群而存在的公益性开发者社区。GDG Shanghai 创立于 2009 年,是全球 GDG 社区中最活跃和知名的技术社区之一,每年举办 30 – 50 场大大小小的科技活动,每年影响十几万以上海为中心辐射长三角地带的开发者及科技从业人员。


社区成员加入方式:请发邮件至以下邮箱

  [email protected]