Flutter学习-28-Flutter的数据共享

258 阅读3分钟

「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战」。

  • 我们有的时候需要在不同页面或者dart文件之间进行传值,比如我们之前页面之间跳转的时候进行通过属性进行传值;还有一种就是我们下面要说的数据共享,只要在widget树下,子widget都可获取。

1. 使用场景

我们定义一个widget,点击的时候数值增加类似初始化的demo

image.png 我们添加一些层级关系,进行嵌套

image.png

这个时候如我我们需要传值的话,就是这样一层一层进行传递,但是我们要是有共享数据的话,就可以避免这样的情况

image.png

2. InheritedWidget

InheritedWidget就像对其他的Widget的一个实现或者说是补充,就像Theme.of(context)返回你能拿到一个ThemeData,并使用其内部自定义的属性改变你当前widget的显示效果

image.png 我们定义一个关于count的InheritedWidget

 class CountData extends InheritedWidget{

  final int countData;//定义共享点击的数据
  const CountData({required this.countData, required Widget childWdiget}) : super(child:  childWdiget);//构造方法
  //定义一个便捷方法,方便子组件中的Widget去获取共享的数据
 static CountData? of(BuildContext context){
   return context.dependOnInheritedWidgetOfExactType<CountData>();
  }

  @override//发送通知
  bool updateShouldNotify(covariant CountData oldWidget) {
    // TODO: implement updateShouldNotify
    return true;
    // throw UnimplementedError();
  }
  

}

我们定义一个类继承InheritedWidget,定义我们要的数据, 我们要实现一下获取数据的方法,我们使用类方法,通过dependOnInheritedWidgetOfExactType当值发生改变的时候是否发送通知。

image.png

可以为空,因此我们也可以使用 泛型我们传我们定义的类CountDataupdateShouldNotify是当值发送改变的时候是否发送推送。 配合didChangeDependencies使用

@override
void didChangeDependencies() {
  // TODO: implement didChangeDependencies
  super.didChangeDependencies();
  print('didChangeDependencies come!');
}
  • 我们在我们Widget树最外层包一层

image.png

数据使用的时候在这个widget树下,通过之前的静态方法获取即可

image.png

  • updateShouldNotify的使用

image.png

countData发送改变的时候我们可以通过这个方法获取旧的值,我们可以比较和新的值是否相等,不相等就return ture。我们之前重写的didChangeDependencies就会收到通知进行调用。

image.png

我们返回false的话,就不会发生通知进行调用了。
最终完整代码:

import 'package:flutter/material.dart';

 class CountData extends InheritedWidget{

  final int countData;//定义共享点击的数据
  const CountData({required this.countData, required Widget childWdiget}) : super(child:  childWdiget);//构造方法
  //定义一个便捷方法,方便子组件中的Widget去获取共享的数据
 static CountData? of(BuildContext context){
   return context.dependOnInheritedWidgetOfExactType<CountData>();
  }

  @override//发送通知
  bool updateShouldNotify(covariant CountData oldWidget) {
    // TODO: implement updateShouldNotify
    print(oldWidget.countData);
    print(countData);

    return oldWidget.countData != countData;
    // throw UnimplementedError();
  }


}
class InheritedWidgetDemo extends StatefulWidget {
  const InheritedWidgetDemo({Key? key}) : super(key: key);

  @override
  _InheritedWidgetDemoState createState() => _InheritedWidgetDemoState();
}

class _InheritedWidgetDemoState extends State<InheritedWidgetDemo> {
  int _count = 0;
  @override
  Widget build(BuildContext context) {
    return CountData(
      childWdiget: Container(
        child:  Center(
            child: Column(

              children: [
                SizedBox(height: 200,),
                Center(
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Center(child: Container(child: Text1(_count))),
                  ),
                ),
                ElevatedButton(onPressed: (){
                  _count ++;
                  setState(() {

                  });
                }, child: Text('点击数字增加')),
              ],
            )
        ),
      ),
      countData: _count,
    );
  }
}
class Text1 extends StatelessWidget {
  final int count;
  const Text1(this.count,{Key? key}) : super(key: key);
  

  @override
  Widget build(BuildContext context) {
    print('test1 come!');

    return Text2(count);
  }
}
class Text2 extends StatelessWidget {
  final int count;
  const Text2(this.count,{Key? key}) : super(key: key);


  @override
  Widget build(BuildContext context) {
    print('test2 come!');

    return Text3(count);
  }
}
class Text3 extends StatefulWidget {
  final int count;
  const Text3(this.count,{Key? key}) : super(key: key);

  @override
  _Text3State createState() => _Text3State();
}

class _Text3State extends State<Text3> {

   @override
  void didChangeDependencies() {
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
    print('didChangeDependencies come!');
  }
  @override

  Widget build(BuildContext context) {
    print('test3 come!');
    return Container(
      child: Text(CountData.of(context)!.countData.toString()),
    );
  }
}