Flutter Provider状态管理学习

195 阅读2分钟

在Flutter中,provider 是一个状态管理库,它提供了多种类型的 Provider 来帮助你管理应用中的状态。以下是几种常见的 Provider 类型及其区别和使用场景:

  1. ListenableProvider:

    • 用途: 用于包装 Listenable 对象,如 ChangeNotifier
    • 特点: 当 Listenable 对象发出通知时,依赖于此 Provider 的 Consumer 或 Selector 会重建。
    • 使用场景: 当你有一个 ChangeNotifier 或任何实现了 Listenable 接口的类,并且想要在状态改变时自动更新UI时。
  2. ChangeNotifierProvider:

    • 用途: 专门用于包装 ChangeNotifier 类。
    • 特点ChangeNotifierProvider 是 ListenableProvider 的一个特例,它自动管理 ChangeNotifier 的生命周期,包括调用 addListener 和 removeListener
    • 使用场景: 当你有一个 ChangeNotifier 类,并且想要在状态改变时自动更新UI,同时希望 provider 库自动处理 ChangeNotifier 的注册和注销。
  3. ValueListenableProvider:

    • 用途: 用于包装 ValueListenable 对象,如 ValueNotifier
    • 特点: 当 ValueListenable 的值改变时,依赖于此 Provider 的 Consumer 或 Selector 会重建。
    • 使用场景: 当你有一个 ValueNotifier 或其他 ValueListenable 对象,并且想要在值改变时自动更新UI时。
  4. StreamProvider:

    • 用途: 用于包装 Stream 对象。
    • 特点: 当 Stream 发出新事件时,依赖于此 Provider 的 Consumer 或 Selector 会重建。
    • 使用场景: 当你有一个 Stream,并且想要在流发出新事件时自动更新UI时。例如,处理实时数据流、网络请求结果等。
代码示例:
  1. ListenableProvider:
class MyChangeNotifier extends ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

void main() {
  runApp(
    MultiProvider(
      providers: [
        ListenableProvider<MyChangeNotifier>(create: (_) => MyChangeNotifier()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  ...
  Consumer<MyChangeNotifier>(
       builder: (context, model, child) => Text(
          '${model.count}',
          style: Theme.of(context).textTheme.headline4,
    ),
 ),
  ElevatedButton(
       onPressed: () => context.read<MyChangeNotifier>().increment(),
       child: Text('Increment'),
  ),
}

  1. ChangeNotifierProvider:
class MyChangeNotifier extends ChangeNotifier {
  // ... 同上
}

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider<MyChangeNotifier>(create: (_) => MyChangeNotifier()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  // ... 同上
}
  1. ValueListenableProvider:
class MyValueNotifier extends ValueNotifier<int> {
  MyValueNotifier() : super(0);

  void increment() {
    value++;
  }
}

void main() {
  runApp(
    MultiProvider(
      providers: [
        ValueListenableProvider<MyValueNotifier, int>(
          create: (_) => MyValueNotifier(),
        ),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
 ...
 Consumer<int>(
       builder: (context, count, child) => Text(
          '$count',
           style: Theme.of(context).textTheme.headline4,
       ),
   ),
 ElevatedButton(
      onPressed: () => context.read<MyValueNotifier>().increment(),
      child: Text('Increment'),
  ),
}
  1. StreamProvider:
class MyStreamController {
  final _controller = StreamController<int>();
  Stream<int> get stream => _controller.stream;

  void increment() {
    _controller.sink.add(1);
  }

  void dispose() {
    _controller.close();
  }
}

void main() {
  runApp(
    MultiProvider(
      providers: [
        StreamProvider<int>(
          create: (_) => MyStreamController().stream,
        ),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
 StreamBuilder<int>(
     stream: Provider.of<Stream<int>>(context),
     builder: (context, snapshot) {
         if (snapshot.hasData) {
            return Text(
               '${snapshot.data}',
               style: Theme.of(context).textTheme.headline4,);
             } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
           }
         return CircularProgressIndicator();
       },
    ),
  ElevatedButton(
      onPressed: () => context.read<MyStreamController>().increment(),
      child: Text('Increment'),
    ),
}

在这些示例中,我们创建了不同的状态管理对象,并使用相应的 Provider 来包装它们。然后,我们在UI中使用 ConsumerSelectorStreamBuilder 来监听状态的变化,并在状态更新时重建UI。