Flutter 状态管理之 InheritedWidget 使用和分析

Flutter 状态管理之 InheritedWidget 使用和分析

InheritedWidget 使用

初识 Flutter 的 Demo 是一个点击按键然后数字增加的小应用,这小应用就涉及到了 Flutter 中的状态管理,核心就是 setState 方法。

setState 方法用于通知 Flutter 更新 Widget 的状态,比如重建当前 Widget 及其子树,它是从上到下进行通知的,但作用域仅停留在当前的 StatefulWidget 范围内。

如果有两个同级的 StatefulWidget ,比如 WidgetA 和 WidgetB ,当 WidgetA 的数据发生改变,想要通知 WidgetB 对应改变。

如果是 Android 的应用开发,采用 MVP 模式的话,需要 Controller 同时持有 WidgetA 和 WidgetB ,当 WidgetA 状态改变时,通过 Controller 对应改变 WidgetB 相关状态就行了。

原文地址:https://glumes.***/flutter-inheritedwidget-usage-and-analysis/

而在 Flutter 中基于 InheritedWidget 控件,通过相应的封装库就可以实现 MVVM 模式的开发,相当快捷方便。

通过如下的例子来学习 InheritedWidget 控件的使用:左边栏和右边栏是两个同级的 Widget ,右边栏中点击修改名称,左边栏中显示对应的修改内容。

因为 InheritedWidget 是从上到下进行数据共享、传递的,所以要把 InheritedWidget 作为根节点,需要共享数据的节点作为子节点。

通过继承 InheritedWidget 实现自定义的控件类:

class DataModelWidget extends InheritedWidget {
   
   
  const DataModelWidget(
      {
   
   super.key,
      required super.child,
      required this.name,
      required this.changeName});

  // 当数据发生改变时,才会通知到子控件
  
  bool updateShouldNotify(covariant DataModelWidget oldWidget) {
   
   
    return oldWidget.name != name;
  }

  // 定义 static 快捷方法,方便在子控件中获取共享数据
  // 当子控件通过 of 方法使用了 InheritedWidget 中的数据,注册依赖关系
  // 此时数据变动会触发 didChangeDependencies 方法
  static DataModelWidget? of(BuildContext context) {
   
   
    return context.dependOnInheritedWidgetOfExactType<DataModelWidget>();
  }

  // 共享的数据
  final String name;
  final Function changeName;
}

要传递的数据就是 name 变量,在一个子控件中去修改 name 的值,在另一个子控件中显示修改内容。这里为了方便直接把要传递的数据放在了 Widget 里面,也可以封装对应的 Model 类,然后 Widget 持有 Model 类会更友好一些。

当数据发生改变时,会通过 updateShouldNotify 方法通知到子控件的 didChangeDependencies 方法。

didChangeDependencies 方法指的是子控件是否有依赖父 Widget 中 InheritedWidget 的数据,如果有就会响应回调。

子控件通过 of 静态方法获取 InheritedWidget 的时候调用了 dependOnInheritedWidgetOfExactType 方法,该方法会将 InheritedWidget 和获取数据的子控件进行注册,这才有了依赖关系。

child 参数就是接下来要写的子控件内容了。

class _DashboardState extends State<Dashboard> {
   
   
  String _name = "glumes";

  
  Widget build(BuildContext context) {
   
   
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Row(
            children: <Widget>[
              // 初始化 InheritedWidget 并传递对应参数
              DataModelWidget(      
                name: _name,
                changeName: _changeUserName,
                child: const ContentBoard(),
              )
            ],
          ),
        ),
      ),
    );
  }
  // 右边栏调用 _changeUserName 方法修改共享数据的值
  void _changeUserName(String userName) {
   
   
    setState(() {
   
   
      _name = userName;
    });
  }
}

把子控件封装在 ContentBoard 中,分别是:

// 左边栏
Text("名称:${
     
     DataModelWidget.of(context)!.name}"),


void didChangeDependencies() {
   
   
  super.didChangeDependencies();
  Log.d("left sidebar change dependencies");
}

// 右边栏
ElevatedButton(
  onPressed: () {
   
   
    DataModelWidget.of(context)!.changeName("change name ${
     
     count.toString()}");
    count++;
  },
  child: <
转载请说明出处内容投诉
CSS教程网 » Flutter 状态管理之 InheritedWidget 使用和分析

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买