接在Windows上搭建Flutter开发环境,并在模拟器上看到myapp中创建的 Flutter 应用,其中会有一个计数器示例的应用模板。
刚开始学习 Flutter 时,在开始编写第一个 Flutter App 前,起码还是需要先完全看懂这块基础的示例代码。
代码如下(对其英文注释进行了一下中文翻译):
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// 这个 Widget 是应用程序的根.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// 这是应用程序的主题。
//
// 试着用“flutter run”运行你的应用程序,你将看到应用程序有一个蓝色的工具栏
// 然后,在不退出应用的情况下, 尝试改变下面 primarySwatch 的颜色为绿色 Colors.green
// 然后调用“热重载”(在你运行“flutter run”的控制台中按“r”,或简单地保存你的修改到“热重载”中的 Flutter IDE)
// 注意,计数器没有重置为零;应用程序没有重新启动
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
//这个 Widget 是你的应用程序主页. 它是有状态的, 表示它具有一个 State 对象 (定义如下),该对象包含影响其外观的字段。
// 这个类是状态的配置. 它保存由父组件(本例中为App Widget)提供的值(本例中为标题),并由 State 的 build 方法使用。
// Widget子类中的字段始终标记为"final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// 调用 setState 告诉 Flutter 框架 State 已发生更改
// 这会导致它重新运行下面的构建方法,以便显示更新的值
// 如果我们在不调用setState()的情况下更改了_counter,那么构建方法就不会再次被调用,因此什么也不会发生
_counter++;
});
}
@override
Widget build(BuildContext context) {
// 每次调用setState时都会重新运行该方法, 例如上面的_incrementCounter方法所做的.
//
//Flutter框架已经过优化,可以快速重新运行构建方法,因此您可以重建任何需要更新的内容,而不必单独更改 Widget 的实例。
return Scaffold(
appBar: AppBar(
// 在这里,我们从由App.build方法创建的MyHomePage对象中获取值,并使用它来设置我们的应用栏标题。
title: Text(widget.title),
),
body: Center(
//Center是一个布局 Widget
//它接受一个子元素并将其放置在父元素中
child: Column(
// Column也是一个布局widget. 它采用一列子元素并将它们垂直排列
// 默认情况下, 它会自行调整大小以使其子元素水平放置,并尝试与父级一样高。
//
// 调用 "debug painting" (在控制台中按“p”, 在 Android Studio 中的 Flutter Inspector 选择 "Toggle Debug Paint"操作)
// 查看每个 widget 的线框
//
// 列具有各种属性来控制其自身大小以及子元素的位置
// 这里我们使用mainAxisAlignment将子元素垂直居中;
// 这里的主轴是垂直轴,因为列是垂直的(交叉轴是水平的)。
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // 该结尾逗号使自动格式化的构建方法更好.
);
}
}
1.最开始第一行代码导入了 Material UI 组件库
Material是一种标准的移动端和web端的视觉设计语言, Flutter 默认提供了一套丰富的 Materia l风格的 UI 组件
2.main 函数为应用程序的入口
- main 函数中调用了 runApp 方法,接受一个 Widget 并使其成为widget树的根(框架强制根widget覆盖整个屏幕),功能是启动 Flutter 应用。(在此示例中它是一个 MyApp 对象,MyApp() 是 Flutter 应用的根组件。)
- main 函数使用了(=>)符号,这是 Dart 中单行函数或方法的简写
3.MyApp继承了 StatelessWidget类,这将会使应用本身成为一个Stateless widgets(无状态组件可以理解为将外部传入的数据转化为界面展示的内容,只会渲染一次)
- 在Flutter中,大多数东西都是widget,包括对齐(alignment)、填充(padding)和布局(layout),它们都是以widget的形式提供。
- widget的主要工作是实现一个build()函数用以构建自身。一个widget通常由一些较低级别widget组成,通过组合、拼装其它基础 widget。(Flutter 在构建页面时,会调用组件的 build 方法。类似于 React 中的 render 方法)
- MaterialApp 是一个 widget(由是Material库中提供的Flutter APP框架),通过它可以设置应用的名称、主题、语言、首页及路由列表等。
4.MyHomePage 是Flutter应用的首页,它继承自StatefulWidget类,表示是一个Stateful widgets(有状态组件是定义交互逻辑和业务数据,可以理解为具有动态可交互的内容界面,会根据数据的变化进行多次渲染)
- 这个类里的第一行,是生成构造函数。当前构造函数冒号 (:) 之后,声明调用父类构造函数(父类的构造函数参数在构造函数执行之前执行)
- 这个 key 属性类似于 React/Vue 中的 key,主要的作用是决定是否在下一次 build 时复用旧的 widget
- 实现一个 stateful widget 至少需要两个类:
一个 StatefulWidget类:StatefulWidget类本身是不变的
一个 State类: State类在widget生命周期中始终存在
5._MyHomePageState 类是 MyHomePage 类对应的状态类,该类持有 MyHomePage widget 的状态。
(以下划线(_)开头,在Dart语言中使用下划线前缀标识符,会强制其变成私有的)
- _counter 该组件的状态
- _incrementCounter 该组件更新状态的自增函数
- Scaffold 是 Material 库中提供的页面脚手架,它提供了默认的导航栏、标题和包含主屏幕widget树
- 剩下的也只是一些组件的属性、函数及事件处理的调用
这里是对 Flutter生命周期 的一点梳理。