我无法让 Riverpod 通知状态更改。我是 Riverpod 的新手,所以我可能误解了它的工作原理。
我想使用 Riverpod 提供一个对象变量,我在另一个小部件树上设置信息,然后再将该类中的信息提供给单独的小部件树中的使用者。这个消费者在功能上充当一种窗口片段,我想在屏幕的这一部分放置一个特定的小部件,由提供的对象中的信息决定。
这是我为对象设置的提供者。
final userPageContext = StateProvider<UserPageContext>((ref) {
return UserPageContext(ptContext: PageTypes.WELCOME);
});
这是我在显示特定小部件之前观察状态变化的消费者。
Consumer(
builder: (context, ScopedReader watch, __) {
final pageContext = watch(userPageContext).state;
return getPageToDisplay(pageContext);
},
),
此函数提供要显示的小部件。
Widget getPageToDisplay(UserPageContext pageContext) {
if (pageContext.entryReady) {
return EntryScreen(entry: pageContext.getNewEntry());
} else {
return Container();
}
}
这是我更改所提供对象状态的构建方法。
@override
Widget build(BuildContext context) {
return Consumer(builder: (_, ScopedReader watch, __) {
final pageContext = watch(userPageContext).state;
return Dialog(
... widgets ...
Row(
... widgets ...
// A button press confirms the users choice and then submits it to the provider
onPressed: () {
Entry entry = Entry(
entryType: entryType,
id: id,
name: name);
pageContext.ptContext = PageTypes.ENTRY;
pageContext.setNewEntry(entry);
pageContext.entryReady = true;
// These pops remove dialog menus that were in the current widget branch
Navigator.of(context).pop();
Navigator.of(context).pop();
},
... widgets ...
),
),
)
],
)
],
),
),
),
);
});
}
这是用于存储状态信息的类。
class UserPageContext {
UserPageContext({required this.ptContext});
late Entry _newEntry;
bool entryReady = false;
/// sets new entry and flags the class state to ready for listeners
void setNewEntry(Entry entry) {
_newEntry = entry;
entryReady = true;
}
Entry getNewEntry() {
entryReady = false;
return _newEntry;
}
PageTypes ptContext;
}
我尝试了许多不同的变体,我以这种方式调用提供者,从 context.read 和 watch 到 watch(object.notifier) 和 watch(object.notifier).state。我想我已经尝试了大部分可能性,所以我不确定这是否可能是我的问题的原因。
-- 小编辑-- 我忘了补充一点,继续执行逻辑似乎工作正常,但在我执行热重载之前状态不会更新。预期页面随即出现。但奇怪的是,页面在再次热加载后立即消失。这似乎表明我提供给提供者的信息在使用后立即被重写,或者我以某种方式没有改变提供者?老实说,我不确定。
预先感谢您,希望您有美好的一天!
答案 0 :(得分:0)
我好像解决了这个问题。我再次尝试使用 ChangeNotifierProvider。将此与扩展的 ChangeNotifier 结合使用,并确保在适当的时间通知 NotifyListeners,似乎可以解决问题。
这是我最终使用的提供程序。
final userPageContext = ChangeNotifierProvider((ref) {
return UserPageContext(ptContext: PageTypes.WELCOME);
});
这些是我对课程所做的更改。
class UserPageContext extends ChangeNotifier {
/// sets new entry and flags the class state to ready for listeners
void setNewEntry(Entry entry) {
... code ...
notifyListeners();
}
...
最后,我第一次尝试 ChangeNotifier 时遇到的一个问题是它似乎没有状态访问权限,类似于许多其他与 Riverpod 一起使用的提供程序的语法。事实证明您不需要那个,因为它只是在您观看时返回您正在寻找的对象。这是我致电提供商的方式。
final pageContext = watch(userPageContext);