flutter 如何用Riverpod 2初始化小部件的提供者?

1wnzp6jl  于 2022-11-30  发布在  Flutter
关注(0)|答案(1)|浏览(162)

我的问题是关于Riverpod的
我有一个小工具有2个选项卡。当我改变选项卡,我想更新一个属性(infoShare)与"地址"值,如果我选择第一个选项卡和"公钥"值,如果我选择第二个选项卡。
我用了通知程序来做这个。没有问题。但是当我第一次示例化主部件时,我的提供程序没有初始化。所以我需要修复它来创建一个特定的提供程序来初始化它,并使用ProviderScope。
这是初始化小部件的好方法吗?
这是我的代码。它可以工作,但我不知道它是否是一个好的解决方案。也许Riverpod的注解可能会有帮助

final _contactDetailInfoShareProviderArgs = Provider<Contact>(
  (ref) {
    throw UnimplementedError();
  },
);

final _contactDetailInfoShareProvider = NotifierProvider.autoDispose
    .family<ContactDetailInfoShareNotifier, String, Contact>(
  () {
    return ContactDetailInfoShareNotifier();
  },
);

class ContactDetailInfoShareNotifier
    extends AutoDisposeFamilyNotifier<String, Contact> {
  ContactDetailInfoShareNotifier();

  @override
  String build(Contact arg) {
    return arg.address.toUpperCase();
  }

  void setInfoShare(int tab, Contact contact) {
    if (tab == 1) {
      state = contact.publicKey.toUpperCase();
    } else {
      state = contact.address.toUpperCase();
    }
  }
}

abstract class ContactDetailProvider {
  static final contactDetailInfoShare = _contactDetailInfoShareProvider;
  static final contactDetailInfoShareProviderArgs =
      _contactDetailInfoShareProviderArgs;
}

class ContactDetail extends ConsumerWidget {
  const ContactDetail({
    required this.contact,
    super.key,
  });

  final Contact contact;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return ProviderScope(
      overrides: [
        ContactDetailProvider.contactDetailInfoShareProviderArgs
            .overrideWithValue(
          contact,
        ),
      ],
      child: ContactDetailBody(
        contact: contact,
      ),
    );
  }
}

class ContactDetailBody extends ConsumerWidget {
  const ContactDetailBody({
    required this.contact,
    super.key,
  });

  final Contact contact;
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Column(
      children: <Widget>[
        Expanded(
          child: Container(
            child: ContainedTabBarView(
              tabs: [
                Text('tab1'),
                Text('tab2'),
              ],
              views: [
                ContactDetailTab1(),
                ContactDetailTab2(),
              ],
              onChange: (p0) {
                ref
                    .watch(
                      ContactDetailProvider.contactDetailInfoShare(contact)
                          .notifier,
                    )
                    .setInfoShare(p0, contact);
              },
            ),
          ),
        ),
        AppButton(
          'Share',
          onPressed: () {
            print(
              ref.watch(
                ContactDetailProvider.contactDetailInfoShare(
                  ref.read(
                    ContactDetailProvider.contactDetailInfoShareProviderArgs,
                  ),
                ),
              ),
            );
          },
        )
      ],
    );
  }
}
jv4diomz

jv4diomz1#

ProviderScope不应用于应用的根目录以外的地方,或者仅用于测试。它不是设计用于小部件中的。有许多其他选项可以初始化提供程序,请考虑使用.family或使用具有三种状态loadingerrorvalueStateNotifierProvider,初始值可以是loading,初始化后可以是value状态。或者考虑使用新的Riverpodcode generation,以使用一些更复杂的逻辑来初始化提供程序。

相关问题