短时状态
只需要在当前的widget中使用的,比如:新建flutter项目的计数器。
应用状态
需要多个部分进行共享的,比如:电商的购物车。
共享状态管理
InheritedWidget
InheritedWidget可以实现跨组件的数据共享,InheritedWidget 是一个类,要使用它需要一个子类继承它,它有一个抽象方法,updateShouldNotify():更新时是否通知didChangeDependencies(),当返回true时会去通知,调用didChangeDependencies(), didChangeDependencies(),是state中的一个生命周期函数。
InheritedWidget构造函数有一个必传参数,widget类型的 child。
然后定义了一个静态方法 of(BuildContext content), 然后通过content 来去查找第一个找到的 MYCounter实例。然后将其返回,这样就可以实现将数据在多个部分的共享。
class MYCounter extends InheritedWidget {
int counter = 100; // 要共享的数据
MYCounter({super.key,required Widget child, this.counter = 0}) : super(child: child);// 构造函数
static MYCounter? of(BuildContext content){ // of 方法
// 沿着Element树,去找到最近的MYCounter
return content.dependOnInheritedWidgetOfExactType();
}
@override
bool updateShouldNotify(covariant InheritedWidget oldWidget) { // 更新时是否通知
return false;
}
}
使用: 实现一个计数器,点击下面的悬浮按钮,计数器自增,悬浮按钮的点击事件,使用setState重新build。实现修改共享的数据,MYDatas(), 中使用 MYCounter的静态方法 of(content)来获取实例,拿到counter数据。MYDatas1()得实现方式相同。
class MYFaxian extends StatefulWidget {
const MYFaxian({super.key});
@override
State<MYFaxian> createState() => _MYFaxianState();
}
class _MYFaxianState extends State<MYFaxian> {
int counter = 10;
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('发现'),
),
// 悬浮按钮
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
// 点击counter自增,使用setState重新build。实现修改共享的数据
setState(() {
counter ++;
});
},
),
body: MYCounter(
counter: counter,
child: Column(
children: [
MYDatas(),
MYDatas1()
],
),
),
);
}
}
class MYDatas extends StatelessWidget {
const MYDatas({super.key});
@override
Widget build(BuildContext context) {
int counter = MYCounter.of(context)!.counter;
return Card(
child: Text('当前数量:$counter'),
);
}
}
class MYDatas1 extends StatelessWidget {
const MYDatas1({super.key});
@override
Widget build(BuildContext context) {
int counter = MYCounter.of(context)!.counter;
return Card(
child: Text('当前数量:$counter'),
);
}
}
从结果我们可以看到,在MYDatas 和MYDatas1中,并没有通过构造函数传入变量,但是我们在点击增加的按钮时,依然实现了数据的共享。