英文:
How to use RiverPod with RefreshIndicator
问题
我有一个事件的ListView,项目通过FutureProvider<List<Event>>下载,工作得很完美,AsyncValue还包括错误和加载小部件。
我想将ListView包装在RefreshIndicator中,这样如果用户拉动列表,它就会重新加载。
最佳方法是什么?我是否可以简单地在onRefresh:行中调用provider.refresh()?
final eventListAsync = ref.watch(eventProvider);
return eventListAsync.when(
data: (eventList) {
eventList.sort((a, b) => a.startTimestamp.compareTo(b.startTimestamp));
return RefreshIndicator(
onRefresh: () async {
await provider.refresh();
},
child: ListView.builder(
itemCount: eventList.length,
itemBuilder: (BuildContext context, int index) {
return eventCard(eventList[index], context);
}),
);
},
error: (err, stack) {
var logger = Logger();
logger.d("Error:$err Stack:$stack");
return Column(
children: [
Text('Error: $err'),
],
);
},
loading: () => const CircularProgressIndicator(),
);
英文:
I have a ListView of events with items downloaded via a FutureProvider<List<Event>>, works perfect, the AsyncValue does the error and loading widgets also.
I want to wrap the ListView in a RefreshIndicator, so that if the user pulls the list down, it gets reloaded.
What's the best way to do this? Can I simply call provider.refresh() in the onRefresh: line?
final eventListAsync = ref.watch(eventProvider);
return eventListAsync.when(
data: (eventList) {
eventList.sort((a, b) => a.startTimestamp.compareTo(b.startTimestamp));
return ListView.builder(
itemCount: eventList.length,
itemBuilder: (BuildContext context, int index) {
return eventCard(eventList[index], context);
});
},
error: (err, stack) {
var logger = Logger();
logger.d("Error:$err Stack:$stack");
return Column( children: [
Text('Error: $err'),
]); },
loading: () => const CircularProgressIndicator(),
);
答案1
得分: 1
你可以使用 ref.refresh(provider)
来更新你的列表。然而,在你的 provider
内部必须具备自初始化的能力。
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RefreshIndicator.adaptive(
onRefresh: () => ref.refresh(provider),
child: ListView(
children: [
Text('你好,世界!'),
],
),
);
}
}
对于更复杂的情况(例如,使用 [Async]Notifier
时),请使用一个单独的更新方法,其中以下逻辑将适用:
void refreshState() {
state = AsyncLoading();
state = AsyncValue.guard(() => /* 调用获取数据的方法 */ );
}
然后在构建方法中使用:
return RefreshIndicator.adaptive(
onRefresh: ref.watch(provider.notifier).refreshState,
child: ListView(
children: [
Text('你好,世界!'),
],
),
);
英文:
You can use ref.refresh(provider)
to update your list. However, within your provider
there must be a self-initialization capability.
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RefreshIndicator.adaptive(
onRefresh: () => ref.refresh(provider),
child: ListView(
children: [
Text('Hello, World!'),
],
),
);
}
}
For more complex cases (e.g. when using [Async]Notifier
) use a separate update method where the following logic would be:
void refreshState() {
state = AsyncLoading();
state = AsyncValue.guard(() => /* call the get data method */ );
}
Then in build method:
return RefreshIndicator.adaptive(
onRefresh: ref.watch(provider.notifier).refreshState,
child: ListView(
children: [
Text('Hello, World!'),
],
),
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论