前言:
flutter中的State生命周期和android以及React Native的生命周期类似。
生命周期的流程图:
初始化
构造函数
initState
didChangeDependencies
new DefaultTabController(length: 3, child: new TabBar(
tabs: [ "主页","订单","我的" ]
.map( (data)=>new Text(data) ).toList(),
@override
void didChangeDependencies() {
super.didChangeDependencies();
_updateTabController();
_initIndicatorPainter();
}
void _updateTabController() {
final TabController newController = widget.controller ?? DefaultTabController.of(context);
...
}
static TabController of(BuildContext context) {
final _TabControllerScope scope = context.inheritFromWidgetOfExactType(_TabControllerScope);
return scope?.controller;
}
运行时
build
didUpdateWidget
组件移除
deactivate
dispose
reassemble
名称
|
状态
|
initState
|
插入渲染树时调用,只调用一次
|
didChangeDependencies
|
state依赖的对象发生变化时调用
|
didUpdateWidget
|
组件状态改变时候调用,可能会调用多次
|
build
|
构建Widget时调用
|
deactivate
|
当移除渲染树的时候调用
|
dispose
|
组件即将销毁时调用
|
实际场景
/*
* Created by 李卓原 on 2018/9/13.
* email: zhuoyuan93@gmail.com
*
*/
import 'package:flutter/material.dart';
class NewsDetailPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => NewsDetailState();
}
class NewsDetailState extends State<NewsDetailPage> {
int text = 1;
NewsDetailState() {
print('构造函数');
}
@override
void initState() {
print('init state');
super.initState();
}
@override
void didChangeDependencies() {
print('didChangeDependencies');
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
print('widget build');
return Scaffold(
body: Center(
child: _loading(),
),
appBar: AppBar(
title: Text('咨询详情'),
),
);
}
@override
void didUpdateWidget(NewsDetailPage oldWidget) {
print('组件状态改变:didUpdateWidget');
super.didUpdateWidget(oldWidget);
}
@override
void deactivate() {
print('移除时:deactivate');
super.deactivate();
}
@override
void dispose() {
print('移除时:dispose');
super.dispose();
}
//预加载布局
Widget _loading() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
strokeWidth: 1.0,
),
Container(
child: Text("正在加载"),
margin: EdgeInsets.only(top: 10.0),
)
],
);
}
}
Tips:
当ListView中的item滚动出可显示区域的时候,item会被从树中remove掉,此item子树中所有的state都会被dispose,state记录的数据都会销毁,item滚动回可显示区域时,会重新创建全新的state、element、renderobject使用hot reload功能时,要特别注意state实例是没有重新创建的,如果该state中存在一下复杂的资源更新需要重新加载才能生效,那么需要在reassemble()添加处理,不然当你使用hot reload时候可能会出现一些意想不到的结果,例如,要将显示本地文件的内容到屏幕上,当你开发过程中,替换了文件中的内容,但是hot reload没有触发重新读取文件内容,页面显示还是原来的旧内容.idChangeDependencies有两种情况会被调用。创建时候在initState 之后被调用在依赖的InheritedWidget发生变化的时候会被调用正常的退出流程中会执行deactivate然后执行dispose。但是也会出现deactivate以后不执行dispose,直接加入树中的另一个节点的情况。这里的状态改变包括两种可能:1.通过setState内容改变2.父节点的state状态改变,导致孩子节点的同步变化。
App生命周期
名称
|
状态
|
resumed
|
可见并能响应用户的输入
|
inactive
|
处在并不活动状态,无法处理用户响应
|
paused
|
不可见并不能响应用户的输入,但是在后台继续活动中
|

微组件
StatelessWidget
-
接收外部数据
-
执行部件构造方法
-
当传入数据改变时会重新渲染UI
StatefulWidget
-
接收外部数据
-
执行部件构造方法和状态初始化方法
-
当传入数据和 本类数据改变时都会重新渲染UI

-
ProductsManager部件初始化
-
创建ProductsManagerState
-
调用ProductsManagerState中的initState方法
-
ProductsManagerState渲染
-
Products部件初始化
-
Products渲染
当点击add product按钮数据发生改变时
1.数据_products发生了变化 通过setState方法通知数据发生了改变 ProductsManagerState build方法被调用 -
而Products进行了重新构造,也就是说当外部数据变化时 Products中的 _products 直接被替换成传入的新数据而不是在修改原有数据

flutter拥有类似于react-native的状态机刷新机制,得益于分离出了StatelessWidget和StatefulWidget,资源分配更加合理的了,代码思路也清晰很多.
组件State的生命周期整理:
创建阶段

Widget状态改变
Log所示:
其他生命周期并没有执行
竖屏切换到横屏执行2次
横屏切换到竖屏执行2次

App切后台,再切回来

销毁阶段


import 'package:flutter/material.dart';
class LifecycleAppPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _LifecycleAppPageState('构造函数');
}
}
class _LifecycleAppPageState extends State<LifecycleAppPage>
with WidgetsBindingObserver {
String str;
int count = 0;
_LifecycleAppPageState(this.str);
@override
void initState() {
print(str);
print('initState');
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeDependencies() {
print('didChangeDependencies');
super.didChangeDependencies();
}
@override
void didUpdateWidget(LifecycleAppPage oldWidget) {
print('didUpdateWidget');
super.didUpdateWidget(oldWidget);
}
@override
void deactivate() {
print('deactivate');
super.deactivate();
}
@override
void dispose() {
print('dispose');
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.inactive:
print('AppLifecycleState.inactive');
break;
case AppLifecycleState.paused:
print('AppLifecycleState.paused');
break;
case AppLifecycleState.resumed:
print('AppLifecycleState.resumed');
break;
case AppLifecycleState.suspending:
print('AppLifecycleState.suspending');
break;
}
super.didChangeAppLifecycleState(state);
}
@override
Widget build(BuildContext context) {
print('build');
return new Scaffold(
appBar: new AppBar(
title: new Text('lifecycle 学习'),
centerTitle: true,
),
body: new OrientationBuilder(
builder: (context, orientation) {
return new Center(
child: new Text(
'当前计数值:$count',
style: new TextStyle(
color: orientation == Orientation.portrait
? Colors.blue
: Colors.red),
),
);
},
),
floatingActionButton: new FloatingActionButton(
child: new Text('click'),
onPressed: () {
count++;
setState(() {});
}),
);
}
}
class LifecyclePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
body: new LifecycleAppPage(),
);
}
}
6 of 7 in the series: Fltter移动开发相关
- sqflite操作相关
- TextField多行操作
- 免费作图工具
- Flutter环境更新方法
- 实体类自动生成工具的配置
实体类自动生成工具的配置
- 理解Flutter widget的生命周期
- 按钮扁平化用法示例-buildFlatButton
按钮扁平化用法示例-buildFlatButton