img

虽然我们通常使用ProviderGetIt在 Flutter 中传递信息,但有时您不想对这些库有任何依赖,而只想定义自己的MyFoo.of(context)查找。通常这是您自己创建包的时候。

有很多深入研究这方面的教程,但在这篇文章中,我们想让它非常简短和甜蜜。

首先,您可能会创建两种主要类型的 InheritedWidgets,Stateless(一些数据)或Stateful(一些控制器)。两者都非常简单,让我们先看看无状态!

创建无状态继承小部件

假设您有一个小部件,并且您希望树中位于您上方的某个人向您传递一些简单的数据。就像您的小部件可能依赖于String您想要继承的特殊功能。

**Step1)**创建一个继承的小部件,它接受您要继承的数据:

class MyPathProvider extends InheritedWidget {
  MyPathProvider ({Key? key, required Widget child, required this.path}) : super(key: key, child: child);
  
  final String path;
  Widget build(BuildContext context) => child;
}

Step2) 将 .of() 和 updateShouldNotify() 方法添加到您的小部件:

static MyPathProvider ? of(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<MyPathProvider>();
@override
// rebuild children if .path value changes
bool updateShouldNotify(covariant MyPathProvider oldWidget) => oldWidget.path != path;

**Step3)**在树中使用小部件:

xxxxxxxxxx return MyPathProvider(path: "some/path", child: ...) 

你完成了!您现在可以尝试使用MyPathProvider.of(context).user来自 MyPathProvider.

创建有状态的 InheritedWidget

第 1 步)创建一个StatefulWidget带孩子的,并声明它的状态为公共。

class MyFoo extends StatefulWidget {
  const MyFoo({Key? key, required this.child}) : super(key: key);
  final Widget child;
  @override
  MyFooState createState() => MyFooState();
}
class MyFooState extends State<MyFoo> {
  @override
  Widget build(BuildContext context) => widget.child;
}

步骤 2) 创建一个匹配的InheritedWidget, 并为您的州设置一个字段。

class _MyInheritedFoo extends InheritedWidget {
  _MyInheritedFoo({Key? key, required Widget child, required this.state}) : super(key: key, child: child);
  final MyFooState state;
  @override
  // Always rebuild children if state changes
  bool updateShouldNotify(covariant InheritedWidget oldWidget) => true;
}

步骤 3) 在状态的build方法中,将 .child 包裹在 中InheritedWidget,并将状态作为参数传递:

Widget build(BuildContext context) {
    return _MyInheritedFoo(child: widget.child, state: this);
  }

步骤 4) 向您的StatefulWidget:

static MyFooState of(BuildContext context) =>
    (context.dependOnInheritedWidgetOfExactType<_MyInheritedFoo>() as _MyInheritedFoo).state;

Step5) 在树中使用小部件 return MyFoo(child: …)

**你完成了!**您现在可以从树中的任何位置查找此状态,只需一个简单的: MyFooState state = MyFoo.of(context);

您可以在 github 上查看完整的工作示例。快乐编码🙂

class MyFoo extends StatefulWidget {
  const MyFoo({Key? key, required this.child}) : super(key: key);
  final Widget child;

  @override
  MyFooState createState() => MyFooState();
  
  static MyFooState of(BuildContext context) =>
    (context.dependOnInheritedWidgetOfExactType<_MyInheritedFoo>() as _MyInheritedFoo).state;
}

class MyFooState extends State<MyFoo> {
  @override
  Widget build(BuildContext context) {
    return _MyInheritedFoo(child: widget.child, state: this);
  }
}

class _MyInheritedFoo extends InheritedWidget {
  _MyInheritedFoo({Key? key, required Widget child, required this.state}) : super(key: key, child: child);
  final MyFooState state;
  @override
  bool updateShouldNotify(covariant InheritedWidget oldWidget) => true;
}