likes
comments
collection
share

Flutter中的InheritedWidge

作者站长头像
站长
· 阅读数 0

在 Flutter 中,InheritedWidget 是一个非常重要的类,它允许沿着 widget 树向下传递数据。这种机制可以使得在 widget 树中较深层次的子 widget 能够访问由其祖先 widget 所持有的数据,而无需通过构造函数手动一层层传递。

基本概念

InheritedWidget 作为一个基类,通常不会直接使用。开发者会创建继承自 InheritedWidget 的自定义类,并在这个类中实现想要共享的数据和逻辑。

当一个 InheritedWidget 被插入到 widget 树中时,它会将自身注册到树上下文(context)中。这样,在树中任何位置的子 widget 都可以通过 context.dependOnInheritedWidgetOfExactType() 方法来获取最近的那个 InheritedWidget 实例,并访问其中包含的数据。

使用步骤

  1. 创建继承自 InheritedWidget 的类:首先需要创建一个新的类并继承自 InheritedWidget。然后添加你希望共享给子 widgets 的数据作为成员变量。
  2. 实现 updateShouldNotify 方法:这个方法用于决定当数据发生变化时是否应该通知依赖于此 InheritedWidget 的子 widgets。如果返回 true,则依赖于此 InheritedWidget 的子 widgets 的 didChangeDependencies() 方法将被调用。
  3. 提供静态方法以方便访问:通常会在继承自 InheritedWidget 的类中提供一个静态方法来简化对共享数据的访问过程。
  4. 在 widget 树中使用:将你创建的 InheritedWidget 放置到 widget 树中合适的位置上,确保它能够覆盖到所有需要访问共享数据的子 widgets。

示例代码

class MyData {
  final String data;

  MyData(this.data);
}

class MyInheritedWidget extends InheritedWidget {
  final MyData myData;

  MyInheritedWidget({
    Key? key,
    required this.myData,
    required Widget child,
  }) : super(key: key, child: child);

  @override
  bool updateShouldNotify(MyInheritedWidget old) {
    return myData != old.myData;
  }

  static MyData of(BuildContext context) {
    final MyInheritedWidget? result = context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
    assert(result != null, 'No MyInherited found in context');
    return result!.myData;
  }
}

class SomeChild extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Accessing the data from the nearest MyInherited instance.
    final myData = MyInheritedWidget.of(context).data;

    return Text(myData);
  }
}

在上面示例代码中:

  • 我们定义了一个名为 MyData 的简单类来存储我们想要共享的数据。
  • 创建了名为 MyInheritedWidget 的类,它继承自 InheritedWidgеt, 并且包含了我们想要共享出去的 MyData.
  • 在静态方法 of() 中,我们使用了上下文(context)来查找最近的那个类型为 MyIhneritedWidgеt 的实例。
  • 在某个子组件(如示例代码中的 SomeChild)里面,我们通过调用静态方法获取并显示了共享数据。

注意事项

  • 当你调用 .of(context) 方法时,Flutter 将会把当前 widget 注册为依赖于找到的最近 InheriedWidgеt。因此当后者更新时前者也会重新构建。
  • 如果你只是想读取 InheriedWidgеt 中包含的数据而不希望注册依赖关系(即不希望重新构建),可以使用 .getElementForIhneritedWidgеtOfExactType().widget as T.

总之,Flutter 中的 InheriedWidgеt 提供了一种高效地在 widget 树间传递和共享数据状态而无需手动传递引用或回调函数等方式。