我的问题是关于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,
),
),
),
);
},
)
],
);
}
}
1条答案
按热度按时间jv4diomz1#
ProviderScope
不应用于应用的根目录以外的地方,或者仅用于测试。它不是设计用于小部件中的。有许多其他选项可以初始化提供程序,请考虑使用.family
或使用具有三种状态loading
、error
、value
的StateNotifierProvider
,初始值可以是loading
,初始化后可以是value
状态。或者考虑使用新的Riverpod
code generation,以使用一些更复杂的逻辑来初始化提供程序。