返回

Provider,八种使用姿势分析

前端

Flutter Provider是Flutter官方推荐的状态管理方案,它基于InheritedWidget实现,提供了一种简单而强大的方式来管理应用程序状态。Provider提供了八种提供者,每种提供者都有其独特的特点和适用场景。

InheritedWidget

InheritedWidget是Provider最基本的一种提供者,它允许子树中的所有组件访问其父组件的状态。InheritedWidget使用起来非常简单,只需要创建一个继承自InheritedWidget的类,并重写其updateShouldNotify方法。

class MyInheritedWidget extends InheritedWidget {
  final String title;

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

  static MyInheritedWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>()!;
  }

  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) {
    return title != oldWidget.title;
  }
}

使用InheritedWidget也非常简单,只需要在子组件中调用MyInheritedWidget.of(context)即可获取父组件的状态。

class MyChildWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = MyInheritedWidget.of(context).title;

    return Text(title);
  }
}

ChangeNotifier

ChangeNotifier是一种特殊的InheritedWidget,它提供了状态改变的通知机制。当ChangeNotifier的状态发生改变时,它会通知其所有的监听者。监听者可以通过调用ChangeNotifier的notifyListeners方法来注册自己。

class MyChangeNotifier extends ChangeNotifier {
  String title = 'Title';

  void setTitle(String title) {
    this.title = title;
    notifyListeners();
  }
}

使用ChangeNotifier也非常简单,只需要创建一个继承自ChangeNotifier的类,并重写其notifyListeners方法。

class MyChildWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final changeNotifier = Provider.of<MyChangeNotifier>(context);

    return Text(changeNotifier.title);
  }
}

ValueListenableBuilder

ValueListenableBuilder是一种特殊的InheritedWidget,它允许子组件监听一个ValueListenable对象的状态改变。当ValueListenable对象的状态发生改变时,ValueListenableBuilder会自动更新其子组件。

class MyValueListenableBuilder extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final value = Provider.of<ValueNotifier<String>>(context).value;

    return Text(value);
  }
}

Consumer

Consumer是一种特殊的InheritedWidget,它允许子组件监听一个Provider对象的状态改变。当Provider对象的状态发生改变时,Consumer会自动更新其子组件。

class MyConsumer extends Consumer<MyChangeNotifier> {
  @override
  Widget build(BuildContext context, MyChangeNotifier changeNotifier, Widget? child) {
    return Text(changeNotifier.title);
  }
}

Selector

Selector是一种特殊的Consumer,它允许子组件只监听Provider对象状态的一部分。这可以减少不必要的更新,提高应用程序的性能。

class MySelector extends Selector<MyChangeNotifier, String> {
  @override
  String select(BuildContext context, MyChangeNotifier changeNotifier) {
    return changeNotifier.title;
  }

  @override
  Widget build(BuildContext context, String title, Widget? child) {
    return Text(title);
  }
}

ProxyProvider

ProxyProvider是一种特殊的Provider,它允许子组件监听多个Provider对象的状态改变。当任何一个Provider对象的状态发生改变时,ProxyProvider会自动更新其子组件。

class MyProxyProvider extends ProxyProvider<String> {
  @override
  Widget build(BuildContext context, String value, Widget? child) {
    return Text(value);
  }
}

StreamProvider

StreamProvider是一种特殊的Provider,它允许子组件监听一个Stream对象的状态改变。当Stream对象的状态发生改变时,StreamProvider会自动更新其子组件。

class MyStreamProvider extends StreamProvider<String> {
  @override
  Stream<String> stream(BuildContext context) async* {
    yield* Stream.periodic(Duration(seconds: 1), (i) => '$i');
  }

  @override
  Widget build(BuildContext context, AsyncSnapshot<String> snapshot, Widget? child) {
    return Text(snapshot.data ?? '');
  }
}

FutureProvider

FutureProvider是一种特殊的Provider,它允许子组件监听一个Future对象的状态改变。当Future对象的状态发生改变时,FutureProvider会自动更新其子组件。

class MyFutureProvider extends FutureProvider<String> {
  @override
  Future<String> future(BuildContext context) async {
    return Future.delayed(Duration(seconds: 1), () => 'Hello, world!');
  }

  @override
  Widget build(BuildContext context, AsyncSnapshot<String> snapshot, Widget? child) {
    return Text(snapshot.data ?? '');
  }
}

总结

Provider提供了八种提供者,每种提供者都有其独特的特点和适用场景。在开发中,您需要根据具体情况选择合适的提供者。

提供者 特点 适用场景
InheritedWidget 最基本的状态管理提供者 简单的数据共享
ChangeNotifier 提供状态改变通知机制的InheritedWidget 需要监听状态改变的组件
ValueListenableBuilder 监听ValueListenable对象状态改变的InheritedWidget 需要监听ValueListenable对象状态改变的组件
Consumer 监听Provider对象状态改变的InheritedWidget 需要监听Provider对象状态改变的组件
Selector 只监听Provider对象状态的一部分的Consumer 需要只监听Provider对象状态的一部分的组件
ProxyProvider 监听多个Provider对象状态改变的Provider 需要监听多个Provider对象状态改变的组件
StreamProvider 监听Stream对象状态改变的Provider 需要监听Stream对象状态改变的组件
FutureProvider 监听Future对象状态改变的Provider 需要监听Future对象状态改变的组件