返回

Flutter BLoC 系列:使用 InheritedWidget 提升 BlocProvider

见解分享

前言

欢迎来到 Flutter BLoC 系列的第二篇文章!在本篇中,我们将探索如何通过使用 InheritedWidget 来优化 BlocProvider 的实现,从而提升应用性能。

1. BLoC 模式回顾

在深入探讨 InheritedWidget 的使用之前,让我们简要回顾一下 BLoC(业务逻辑组件)模式。BLoC 是一种设计模式,它将业务逻辑与 UI 组件分离开来。通过使用 BLoC,我们可以实现更清晰、更易于维护的代码库。

2. BlocProvider 的传统实现

在 Flutter 中,BlocProvider 通常用作向小部件提供 BLoC 实例的便利方法。传统上,BlocProvider 是使用一个带有附加 BuildContext 的简单回调函数来实现的。

class BlocProvider<T extends Bloc> extends StatefulWidget {
  final T bloc;
  final Widget child;

  const BlocProvider({Key key, @required this.bloc, @required this.child}) : super(key: key);

  @override
  _BlocProviderState<T> createState() => _BlocProviderState<T>();
}

3. InheritedWidget 的优势

使用 InheritedWidget 可以为 BlocProvider 带来的一个主要优势是性能提升。InheritedWidget 会在小部件树的上下文中存储数据,这样就可以在需要时快速访问这些数据,而无需重新构建整个小部件树。

4. 使用 InheritedWidget 实现 BlocProvider

要使用 InheritedWidget 实现 BlocProvider,我们需要创建一个新的类 BlocProviderInherited 来继承 InheritedWidget 类。这个类将存储我们的 BLoC 实例。

class BlocProviderInherited<T extends Bloc> extends InheritedWidget {
  final T bloc;

  const BlocProviderInherited({Key key, @required this.bloc, @required Widget child}) : super(key: key, child: child);

  static T of<T extends Bloc>(BuildContext context) {
    final provider = context.dependOnInheritedWidgetOfExactType<BlocProviderInherited<T>>();
    return provider.bloc;
  }

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => false;
}

然后,我们可以用新的 BlocProviderInherited 类来替换 BlocProvider 小部件。

class BlocProvider<T extends Bloc> extends StatelessWidget {
  final T bloc;
  final Widget child;

  const BlocProvider({Key key, @required this.bloc, @required this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProviderInherited<T>(
      bloc: bloc,
      child: child,
    );
  }
}

5. 使用示例

使用新的 BlocProvider 类与使用旧版本类似。我们只需将 BlocProvider 小部件包装在我们的 UI 组件周围,并通过 BlocProvider.of<T>(context) 访问 BLoC 实例。

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final bloc = BlocProvider.of<MyBloc>(context);
    // 使用 bloc...
  }
}

6. 结论

通过使用 InheritedWidget,我们成功地提升了 BlocProvider 的性能。这种优化对于拥有复杂小部件树的应用程序特别有用,因为它可以减少不必要的重建次数,从而提高应用程序的整体性能。

感谢阅读!请随时提出问题或建议。