【活动回顾】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 之间通信,可以减少性能开销。
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
对象。
以下是一个简单的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
里的东西,比如State
和RenderObject
。
Widget
有很多类别,接下来我们进一步展开。
part 2.1—StatelessWidget
在上面的示例中,我们已经看到了StatelessWidget
,StatelessWidget
相对比较简单,它继承自Widget
类,重写了createElement()
方法:
@override
StatelessElement createElement() => new StatelessElement(this);
StatelessElement
间接继承自Element
类,与StatelessWidget
相对应(作为其配置数据)。StatelessWidget
用于不需要维护状态的场景,它通常在build
方法中通过嵌套其它Widget来构建UI,在构建过程中会递归的构建其嵌套的Widget
。
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
间接继承自Element
类,与StatefulWidget
相对应(作为其配置数据)。StatefulElement
中可能会多次调用createState()
来创建状态(State)对象。
•createState()
用于创建和StatefulWidget
相关的状态,它在StatefulWidget
的生命周期中可能会被多次调用,本质上就是一个StatefulElement
对应一个 State 实例。
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,
),
),
),
);
}
}
part 2.4—容器Widget和渲染Widget
Text
, Slider
, ListTile
等都属于渲染Widget,其内部主要是RenderObjectElement
。
StatelessWidget
和StatefulWidget
等属于容器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 的底层原理,但这一部分较为复杂,限于篇幅原因这里就不再深入阐述了,各位读者可以通过官方文档进行进一步学习。
Google Developer Groups 谷歌开发者社区,是谷歌开发者部门发起的全球项目,面向对 Google 和开源技术感兴趣的人群而存在的公益性开发者社区。GDG Shanghai 创立于 2009 年,是全球 GDG 社区中最活跃和知名的技术社区之一,每年举办 30 – 50 场大大小小的科技活动,每年影响十几万以上海为中心辐射长三角地带的开发者及科技从业人员。
社区成员加入方式:请发邮件至以下邮箱