Reputation: 803
In my Flutter app, I have a function gotoPage() that animates a PageView widget to a new page. I'd like this function to be called whenever newPageProvider is updated. How do I "activate" the ref.watch() inside the function gotoPage() when gotoPage() is not part of build() function?
providers.dart
final newPageProvider = StateProvider<int>((ref) => 0);
widget.dart
class _WidgetState extends ConsumerState<WidgetState> {
final pageController = PageController(
initialPage: 0,
);
@override
Widget build(BuildContext context) {
return PageView.builder(
controller: pageController,
itemCount: data.length,
itemBuilder: (context, index) {
return WidgetCard(poi: data[index], itemIndex: index);
},
);
}
void gotoPage() {
final index = ref.watch(newPageProvider);
pageController.animateToPage(
index,
);
}
}
Upvotes: 5
Views: 6616
Reputation: 12673
EDIT: Use ref.listen
in build()
instead.
Like so:
@override
Widget build(BuildContext context){
ref.listen(
newPageProvider,
(oldIndex, newIndex){
pageController.animateToPage(newIndex);
}
);
return Scaffold(...);
}
Upvotes: 2
Reputation: 803
I believe the answer is use ref.listen, not ref.watch (as shown below).
From the RiverPod user guide:
Similarly to ref.watch, it is possible to use ref.listen to observe a provider.
The main difference between them is that, rather than rebuilding the widget/provider if the listened provider changes, using ref.listen will instead call a custom function.
The listen method should not be called asynchronously, like inside onPressed or an ElevatedButton. Nor should it be used inside initState and other State life-cycles.
providers.dart
final newPageProvider = StateProvider<int>((ref) => 0);
widget.dart
class _WidgetState extends ConsumerState<WidgetState> {
final pageController = PageController(
initialPage: 0,
);
@override
Widget build(BuildContext context) {
ref.listen<int>(newPageProvider, (int previousIndex, int newIndex) {
_gotoPage(newIndex);
});
return PageView.builder(
controller: pageController,
itemCount: data.length,
itemBuilder: (context, index) {
return WidgetCard(poi: data[index], itemIndex: index);
},
);
}
void gotoPage(index) {
pageController.animateToPage(
index,
);
}
}
Upvotes: 5