Flutter状态基础知识
Widge的状态管理主要分为三种场景
-
Widget自身状态管理
状态有关界面外观效果的(颜色、动画)
-
子Widget状态管理
状态有关用户数据(复选框的选中状态、滑块位置)
-
父Widget和子Widget都存在的状态管理
某一个状态是不同Widget共享的
状态生命周期
有状态的Widget的状态生命周期,主要是在用户参与的相关情况下,对于相关联的组件从创建、现实、更新、停止、销毁的各个阶段。Flutter的有状态的生命周期如下图所示:
从上图可以知道,大概可以分为三个阶段
- 初始化阶段
- 更新阶段
- 销毁阶段
在初始化阶段中,主要是由构造函数、状态创建、状态依赖、视图构建等生命周期构成。涉及的内容主要有
-
构造函数
生命周期的起点,通过调用createState()来创建一个状态
-
initState()
仅仅被调用一次
-
didChangeDependencies()
用来处理状态组件依赖关系变化,在initState()被调用后进行调用
-
build()
用于构建视图
在更新阶段,主要是涉及组件的状态更新操作。在更新阶段中所涉及到的内容主要有
-
setState()
通过调用该函数,告知系统更新后数据重建视图
-
didChangeDependencies()
当状态组件的依赖关系发生变化后,会自动回调,从而触发组件的构建操作
-
didUpdateWidget()
配置发生变化或者热重载时,系统会回调该函数从而进行更新视图
在销毁阶段,主要用来移除或销毁组件。在销毁阶段中涉及到的内容主要有
-
deactivate()
组件内可见状态发生变化时,会被调用,此时组件会暂时被移除
-
dispose()
组件需要永久性被移除时调用,组件被销毁。在调用前,可以进行清理工作
自身状态管理
当Widget自身的状态需要改变时,调用setState(),从而进行视图重绘。
父子组件状态管理
子状态往往是一个无状态的组件,父Widget只需要告诉子Widget什么时候需要更新即可。示例代码如下:
son.dart
子组件是一个无状态的组件,其状态的改变都是根据父组件进行更新的。
import 'package:flutter/material.dart';
class TapBoxB extends StatelessWidget {
const TapBoxB({Key? key, this.active = false, required this.onChanged})
: super(key: key);
final bool active;
final ValueChanged<bool> onChanged;
void _handleTap() {
onChanged(!active);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _handleTap,
child: Container(
child: Center(
child: Text(
active ? 'Active' : 'Inactive',
style: const TextStyle(fontSize: 32.0, color: Colors.white),
textDirection: TextDirection.ltr,
),
),
width: 200.0,
height: 200.0,
decoration: BoxDecoration(
color: active?Colors.lightGreen[700]:Colors.grey[600],
),
),
);
}
}
parent.dart
父组件是一个有状态的组件,父组件通过子组件的构造函数将当前状态传递给TapBoxB,从而让其接收到状态后进行渲染操作。
import 'package:flutter/material.dart';
import 'package:flutter_demo/son.dart';
void main()=>runApp(ParentWidget());
class ParentWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return ParentWidgetState();
}
}
class ParentWidgetState extends State<ParentWidget>{
bool _active=false;
void _handleTapBoxChanged(bool newValue){
setState(() {
_active=newValue;
});
}
@override
Widget build(BuildContext context) {
return Container(
child: TapBoxB(
active: _active,
onChanged: _handleTapBoxChanged,
),
);
}
}
上面的代码运行后的结果如下
混合状态管理
子组件自身管理一些内部状态,父组件管理其他外部状态。在此中模式下,子组件使用构造函数接收父组件传递的状态,并使用回调函数返回子组件内部的状态。