0
点赞
收藏
分享

微信扫一扫

Riverpod的使用方式

萨科潘 2023-12-13 阅读 66

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

/// provider的创建和读取,以及如何在main方法中初始化provider

/// 所有provider都必须放到全局变量,并且加final,
/// 可以用于创建一个Service单例,provider默认是lazy的,第一次使用时provider时才会创建Service
/// 快速创建provider可以使用 Android Studio plugin :Flutter Riverpod Snippets ,
final _serviceProvider = Provider<_Service>((ref) {
  return _Service();
});

class _Service {
  int count = 10;
}

///可以在provider create方法中读取其他provider
final _pushUtilProvider = Provider<_PushUtil>((ref) {
  print("从provider create 方法 中读取provider ${ref.read(_serviceProvider).count}");
  return _PushUtil();
});

class _PushUtil {}

///或直接将ref传入PushUtil
final pushUtilProvider1 = Provider<_PushUtil1>((ref) {
  return _PushUtil1(ref);
});

class _PushUtil1 {
  _PushUtil1(this.ref);

  Ref ref;

  void test() {
    print("从provider 中读取provider ${ref.read(_serviceProvider).count}");
  }
}

class ProviderPage extends ConsumerWidget {
  const ProviderPage(this.title, {Key? key}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: Text(title)),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              "在widget中读取provider: ",
              style: TextStyle(color: Colors.red),
            ),

            ///在widget 中读取provider有三种方式,都需要通过使用WidgetRef.read
            ///第一种使用Consumer,builder方法的第二个参数就是WidgetRef
            Consumer(
              builder: (_, ref, __) {
                return Text("使用Cosnumer 读取provider: ${ref.read(_serviceProvider).count}");
              },
            ),

            ///第二种使用ConsumerWidget
            const _TestConsumerWidget(),

            ///第二种使用ConsumerStatefulWidget
            const _TestConsumerStatefulWidget(),
            const SizedBox(height: 20),
            const Text(
              "在provider 中读取其他provider: ",
              style: TextStyle(color: Colors.red),
            ),
            ElevatedButton(
              onPressed: () {
                /// 因为provider是懒加载的, 所以provider create方法只会在第一次使用的时候调用
                ref.read(_pushUtilProvider);
              },
              child: const Text("从provider create 方法中读取其他provider"),
            ),
            ElevatedButton(
              onPressed: () {
                /// 因为provider是懒加载的, 所以如果想要在APP一开始就初始化,比如flutter_sdk_base中的PushUtil,例如
                /// https://gitlab.xixitime.com/flutter/app/flutter_partner_training_ai/blob/dev_v2.7.0/lib/providers/push_util_provider.dart
                /// 需要将在main中添加
                ///     final container = ProviderContainer();
                //     container.read(pushUtilProvider1);
                //     runApp(UncontrolledProviderScope(
                //         container: container,
                //         child: const MyApp()));
                ref.read(pushUtilProvider1).test();
              },
              child: const Text("从provider 中读取其他provider"),
            ),
          ],
        ),
      ),
    );
  }
}

/// ConsumerWidget == StatelessWidget,只不过在build方法中多了一个WidgetRef参数
/// 也可以使用Flutter Riverpod Snippets 快速创建
class _TestConsumerWidget extends ConsumerWidget {
  const _TestConsumerWidget({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Text("使用CosnumerWidget 读取provider: ${ref.read(_serviceProvider).count}");
  }
}

/// ConsumerWidget == StatefulWidget,只不过在state中多了一个WidgetRef属性
/// 也可以使用Flutter Riverpod Snippets 快速创建
class _TestConsumerStatefulWidget extends ConsumerStatefulWidget {
  const _TestConsumerStatefulWidget({
    Key? key,
  }) : super(key: key);

  @override
  ConsumerState createState() => __TestConsumerStatefulWidgetState();
}

class __TestConsumerStatefulWidgetState extends ConsumerState<_TestConsumerStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Text("使用ConsumerStatefulWidget 读取provider: ${ref.read(_serviceProvider).count}");
  }
}

ChangeNotifier 是 Flutter SDK 中的一个简单的类。它用于向监听器发送通知。换言之,如果被定义为 ChangeNotifier,你可以订阅它的状态变化。(这和大家所熟悉的观察者模式相类似)。在 provider 中,ChangeNotifier 是一种能够封装应用程序状态的方法。对于特别简单的程序,你可以通过一个 ChangeNotifier 来满足全部需求。在相对复杂的应用中,由于会有多个模型,所以可能会有多个 ChangeNotifier。 (不是必须得把 ChangeNotifier 和 provider 结合起来用,不过它确实是一个特别简单的类)。


举报

相关推荐

0 条评论