【问题标题】:Refresh FutureProvider without showing loader刷新 FutureProvider 而不显示加载器
【发布时间】:2021-07-19 07:49:53
【问题描述】:

我有一个钱包提供商,它使用未来的提供商从服务器获取钱包余额,一切正常,我遇到的唯一问题是刷新钱包提供商以使用 context.refresh 从服务器获取最新数据(钱包提供者)。这很好用,但我不希望加载小部件在尝试从服务器获取新数据时显示,而是在新数据从服务器返回之前显示旧数据。

下面是代码:

final walletProvider =
    FutureProvider<WalletModel>((ref) => WalletService().fetchWalletBalance());
Consumer(builder: (context, watch, child) {
final wallet = watch(walletProvider);


return Column(
 children: [
  wallet.when(
   data: (value) {
   return walletContainer(
  context: context, walletModel: value);
},
  loading: () => walletLoading(),
   error: (err, stack) {
  return Text(
'${err.toString()}',
 },
)
],
),

然后我从一个按钮调用context.refresh(walletProvider);,它会刷新但显示加载器小部件,这不是我想要的。我希望在刷新时显示以前的数据。

请帮忙看看如何实现这个目标?

【问题讨论】:

    标签: flutter dart provider riverpod


    【解决方案1】:

    未来可能会有更好的解决方案 (see this issue)。

    然而,与此同时,我想出了一个解决方案,应该会产生你想要的行为。

    final myFutureProvider = FutureProvider.autoDispose<List<int>>((ref) async {
      return Future.delayed(
        const Duration(seconds: 2),
        () => List<int>.generate(100, (_) => Random().nextInt(1000)),
      );
    });
    
    final cachedProvider = StateProvider.autoDispose<List<int>>((ref) => []);
    
    class ExampleListView extends StatelessWidget {
      const ExampleListView({Key? key, required this.data}) : super(key: key);
    
      final List<int> data;
    
      @override
      Widget build(BuildContext context) {
        return ListView.builder(
          itemCount: data.length,
          itemBuilder: (context, index) => ListTile(title: Text(data[index].toString())),
        );
      }
    }
    
    class Refresher extends ConsumerWidget {
      const Refresher({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context, ScopedReader watch) {
        return RefreshIndicator(
          onRefresh: () async {
            await context.refresh(myFutureProvider);
          },
          child: watch(myFutureProvider).when(
            loading: () {
              final cachedData = watch(cachedProvider).state;
              return cachedData.isNotEmpty
                  ? ExampleListView(data: cachedData)
                  : Center(child: CircularProgressIndicator());
            },
            error: (e, s) => Text(''),
            data: (data) {
              WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
                watch(cachedProvider).state = data;
              });
              return ExampleListView(data: data);
            },
          ),
        );
      }
    }
    

    本质上,我们将以前的数据保存到 StateProvider 中,以便在加载新数据时继续显示以前的数据。我将此示例设为通用,因此它处于准备就绪状态,您可以在将其应用到您的代码之前尝试一下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-04
      • 2011-11-29
      • 1970-01-01
      • 2012-09-16
      相关资源
      最近更新 更多