Flutter InheritedWidget、provider数据共享

1.继承InheritedWidget定义需要共享的数据


class ShareDateWidget extends InheritedWidget {
  final String data;//需要共享的数据

  const ShareDateWidget({Key? key, required Widget child, required this.data})
      : super(key: key, child: child);

	//获取当前共享的数据,方便使用者访问
  static ShareDateWidget? of(BuildContext context) =>
      context.dependOnInheritedWidgetOfExactType<ShareDateWidget>();
	

  @override
  bool updateShouldNotify(covariant ShareDateWidget oldWidget) =>
  		//判断改变的数据和原来的数据是否是相同的,如果不相同则返回true通知子树中依赖data的Widget重新build
  		//返回true就会重新build否则不会
  		//同时如果返回false使用者的didChangeDependencies方法也不会被调用
      oldWidget.data != data;
}

2.定义两个使用者


class _TestWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _TestWidgetState();
}
class _TestWidgetState extends State<_TestWidget> {
  @override
  Widget build(BuildContext context) =>
      Text('Widget Top:${ShareDateWidget.of(context)?.data ?? ""}');

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (kDebugMode) {
      print("Dependencies change");
    }
  }
}


class _Test2Widget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _Test2WidgetState();
}

class _Test2WidgetState extends State<_Test2Widget> {
  @override
  Widget build(BuildContext context) =>
      Text('Widget Bottom:${ShareDateWidget.of(context)?.data ?? ""}');

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (kDebugMode) {
      print("Dependencies change");
    }
  }
}

如果使用者共享使用的InheritedWidget的数据就会回调使用者didChangeDependencies方法

3.实现一个按钮点击改变ShareDateWidget的共享数据


class _TestPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _TestPageState();
}

class _TestPageState extends State<_TestPage> {
  String text = "text ";

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          body: ShareDateWidget(
            data: text,
            child: Container(
              alignment: Alignment.center,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  _TestWidget(),
                  ElevatedButton(
                      onPressed: () {
                        setState(() {
                          text = '当前时间:${DateTime.now()}';
                        });
                      },
                      child: const Text('改变数据')),
                  _Test2Widget(),
                ],
              ),
            ),
          ),
        ),
      );
}

最后出来的效果就是只要点击按钮就会改变ShareDateWidgetdata数据:
最后出来的效果就是只要点击按钮就会改变ShareDateWidget的data数据

按照InheritedWidget的逻辑官方还提供了一个provider

1.创建数据共享模板:

引入插件pubspec.yaml

dependencies:
	provider: ^6.0.2

数据共享模板

class HomeMode extends ChangeNotifier {
  String homeData = "正在获取...";

  void getHomeData() {
  //通过接口获取数据
    callGET(ServiceUrl.home, result: (result) {
    //获取数据正常,发送通过更新数据
      homeData = result.toString();
      notifyListeners();
    }, resultErr: (error, stark) {
      homeData = error.toString();
      notifyListeners();
    });
  }
}

2.使用数据

使用数据最外层用ChangeNotifierProvider包裹

class HomeNewPage extends StatelessWidget {
  const HomeNewPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) => ChangeNotifierProvider(
        create: (context) => HomeMode(),
        child: const HomeNewWidget(),
      );
}

订阅数据


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

  @override
  State<StatefulWidget> createState() => HomeState();
}

class HomeState extends State<HomeNewWidget> {
  @override
  void initState() {
    super.initState();
    //请求获取数据
    context.read<HomeMode>().getHomeData();
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        body: Container(
          alignment: Alignment.center,
          child: Text(context.watch<HomeMode>().homeData),
        ),
      );
}


版权声明:本文为qq_30005223原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。