一统天下 flutter - widget 状态管理: 状态管理 - InheritedWidget(在树上,父共享数据后,任意子可获取此数据)

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

一统天下 flutter - widget 状态管理: 状态管理 - InheritedWidget(在树上,父共享数据后,任意子可获取此数据)

示例如下:

lib\state\inherited_widget.dart

/*
 * 状态管理 - InheritedWidget(在树上,父共享数据后,任意子可获取此数据)
 *
 * 在父 Widget 中通过 InheritedWidget 共享一个数据,然后在其任意子 Widget 中都能获取此共享数据
 *
 * 注:比如 Scaffold.of(context), Theme.of(context), Navigator.of(context) 之类的都是通过 InheritedWidget 实现的
 */

import 'package:flutter/material.dart';

import '../helper.dart';

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 Scaffold(
      appBar: null,
      body: MyInheritedWidget(      /// 父 Widget 使用自定义 InheritedWidget
        count: _count,              /// 需要在子树中共享的自定义数据
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: const [
              MyWidget1(),          /// 所有子节点均可以使用自定义 InheritedWidget 中的自定义数据
              Center(
                child: MyWidget2(), /// 所有子节点均可以使用自定义 InheritedWidget 中的自定义数据
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          setState(() {
            _count += 1;
          });
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}


class MyWidget1 extends StatelessWidget {
  const MyWidget1({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      width: 100,
      height: 100,
      alignment: Alignment.center,
      child: MyText(
        /// 通过 .of() 使用自定义 InheritedWidget 实例
        MyInheritedWidget.of(context)!.count.toString(),
      ),
    );
  }
}

class MyWidget2 extends StatefulWidget {
  const MyWidget2({Key? key}) : super(key: key);
  @override
  _MyWidget2State createState() => _MyWidget2State();
}
class _MyWidget2State extends State<MyWidget2> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.green,
      width: 100,
      height: 100,
      alignment: Alignment.center,
      child: MyText(
        /// 通过 .of() 使用自定义 InheritedWidget 实例
        MyInheritedWidget.of(context)!.count.toString(),
      ),
    );
  }
}


/// 自定义 InheritedWidget
/// 用于在父 Widget 中通过 InheritedWidget 共享一个数据,然后在其任意子 Widget 中都能获取此共享数据
class MyInheritedWidget extends InheritedWidget {
  const MyInheritedWidget({Key? key, required Widget child, required this.count}) : super(key:key, child: child);

  /// 需要和子树共享的数据
  final int count;

  /// 这个 of() 是一个约定,子树可以通过 MyInheritedWidget.of(context) 的方式获取实例
  /// 原生的 Scaffold.of(context), Theme.of(context), Navigator.of(context) 之类的都是这么实现的
  static MyInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }

  /// 是否需要通知子树中所有使用了 .of() 的 Widget 重新 build
  @override
  bool updateShouldNotify(covariant MyInheritedWidget oldWidget) {
    return count != oldWidget.count;
  }
}

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

posted @ 2023-03-22 10:58  webabcd  阅读(27)  评论(0编辑  收藏  举报