Flutter跨组件传递数据

除了属性传值,对于数据的跨层传递,Flutter 还提供了三种方案:InheritedWidget,Notification,EventBus。

InheritedWidget

InheritedWidget 是 Flutter 中的一个功能型 Widget,适用于在 Widget 树中共享数据的场景。通过它,我们可以高效地将数据在 Widget 树中进行跨层传递。

Theme 类是通过 InheritedWidget 实现的典型案例。

不过,InheritedWidget 仅提供了数据读的能力,如果我们想要修改它的数据,则需要把它和 StatefulWidget中的 State 配套使用。

class CountContainer extends InheritedWidget {
  ...
  final _MyHomePageState model;// 直接使用 MyHomePage 中的 State 获取数据
  final Function() increment;

  CountContainer({
    Key key,
    @required this.model,
    @required this.increment,
    @required Widget child,
  }): super(key: key, child: child);
  ...
}

class _MyHomePageState extends State {
  int count = 0;
  void _incrementCounter() => setState(() {count++;});// 修改计数器

  @override
  Widget build(BuildContext context) {
    return CountContainer(
      model: this,// 将自身作为 model 交给 CountContainer
      increment: _incrementCounter,// 提供修改数据的方法
      child:Counter()
    );
  }
}

class Counter extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 获取 InheritedWidget 节点
    CountContainer state = CountContainer.of(context);
    return Scaffold(
      ...
      body: Text(
        'You have pushed the button this many times: ${state.model.count}', // 关联数据读方法
      ),
      floatingActionButton: FloatingActionButton(onPressed: state.increment), // 关联数据修改方法
    );
  }
}

Notification

如果说 InheritedWidget 的数据流动方式是从父Widget 到子 Widget 逐层传递,那Notification恰恰相反,数据流动方式是从子 Widget 向上传递至父 Widget。这样的数据传递机制适用于子 Widget 状态变更,发送通知上报的场景。

想要实现自定义通知,我们首先需要继承 Notification类,Notification 类提供了 dispatch 方法,可以让我们沿着 context 对应的 Element 节点树向上逐层发送通知。然后使用 NotificationListener 在父 Widget 监听来自子 Widget 的事件。

EventBus

这种是无需发布者与订阅者之间存在父子关系的数据同步机制。

EventBus 是一个第三方插件,因此我们需要在 pubspec.yaml 文件中声明它:

dependencies:  
  event_bus: 1.1.0

分别概括属性传值、InheritedWidget、Notification 与 EventBus 的优缺点。

项目
属性传值 使用简单 跨越很多层传递给子组件繁琐而且冗余
InheritedWidget 跨多个父子节点方便 修改数据麻烦,传值方向的单一,从上往下
Notification 向上传递事件方便 监听通知读取麻烦,传值方向的单一,从下往上
EventBus 订阅、发布。全局使用,无需组件间存在父子关系 要订阅和解订阅,效率不高

你可能感兴趣的:(Flutter)