如何在RefreshIndicator中使用RiverPod

huangapple go评论39阅读模式
英文:

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) =&gt; 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(&quot;Error:$err Stack:$stack&quot;);
      return Column( children: [

           Text(&#39;Error: $err&#39;),

    ]); },
    loading: () =&gt; 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: () =&gt; ref.refresh(provider),
      child: ListView(
        children: [
          Text(&#39;Hello, World!&#39;),
        ],
      ),
    );
  }
}

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(() =&gt; /* call the get data method */ );
}

Then in build method:

return RefreshIndicator.adaptive(
      onRefresh: ref.watch(provider.notifier).refreshState,
      child: ListView(
        children: [
          Text(&#39;Hello, World!&#39;),
        ],
      ),
    );

huangapple
  • 本文由 发表于 2023年6月8日 18:41:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76431008.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定