flutter 状态管理

92 阅读2分钟

短时状态

只需要在当前的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'),
    );
  }
}

1681874194740.png

从结果我们可以看到,在MYDatas 和MYDatas1中,并没有通过构造函数传入变量,但是我们在点击增加的按钮时,依然实现了数据的共享。