flutter入门序章
本系列文章共有三篇,计划分别从Flutter、Dart、工具三个方面介绍,快速形成对Flutter开发的一个综合概念。
本文主要介绍Flutter相关知识。
Flutter语言使用 Dart,开发IDE使用VSCode、Android Studio 或 IntelliJ IDEA,个人推荐使用VSCode。
Flutter概览
Flutter是由Google开发的开源移动应用开发框架,用于快速构建高性能、高保真度的跨平台移动应用。Flutter支持同一套代码在 iOS、Android、Web、桌面应用等多个平台上运行,使用自带的 Skia 图形引擎,可以直接绘制 UI 组件,这使得 Flutter 应用在性能方面表现出色,滚动流畅,响应迅速(目前正在使用 Impeller 替换 Skia)。
看一眼有个印象即可。
参考资料
三棵树
Flutter的渲染机制由三棵树组成:Widget Tree、Element Tree、Render Tree(渲染树)。
所有Widget组成Widget Tree。
通过调用Widget的createElement()方法,创建Element Tree,Wdiget Tree与Element Tree是一一对应的。
每个Element调用 createRenderObject()形成Render Tree,Render Tree负责渲染,注意Render Tree与Elemeng Tree并不是一一对应的,而是为最后渲染做准备。
StatelessWidget
// StatelessWidget 定义
abstract class StatelessWidget extends Widget {
const StatelessWidget({ super.key });
@override
StatelessElement createElement() => StatelessElement(this);
// 核心是 build 方法
@protected
Widget build(BuildContext context);
}
// 示例,Echo widget,核心是build方法构建UI
class Echo extends StatelessWidget {
const Echo({
Key? key,
required this.text,
this.backgroundColor = Colors.grey, //默认为灰色
}):super(key:key);
final String text;
final Color backgroundColor;
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: backgroundColor,
child: Text(text),
),
);
}
}
// 在子树中获取父级widget的一个示例:
class ContextRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Context测试"),
),
body: Container(
child: Builder(builder: (context) {
// 在 widget 树中向上查找最近的父级`Scaffold` widget
Scaffold scaffold = context.findAncestorWidgetOfExactType<Scaffold>();
// 直接返回 AppBar的title, 此处实际上是Text("Context测试")
return (scaffold.appBar as AppBar).title;
}),
),
);
}
}
StatefulWidget
StatefulWidget的核心就是有状态,可以修改重绘UI。
StatefulWidget重写了createElement方法,返回的是StatefulElement,StatefulElement可能会多次调用createState()来创建对象。
createState(),创建状态,修改UI必须通过修改状态来实现,一个StatefulElement对应一个State实例。
abstract class StatefulWidget extends Widget {
const StatefulWidget({ Key key }) : super(key: key);
@override
StatefulElement createElement() => StatefulElement(this);
@protected
State createState();
}