You need to enable JavaScript to run this app. 使用FutureProvider时监听数据变化重建ListView.builder实现SQFlite搜索
优惠活动
大模型
产品
解决方案
定价
更多

使用FutureProvider时监听数据变化重建ListView.builder实现SQFlite搜索

核心问题

你当前的方案无法触发UI更新的根本原因是:FutureProvider的create方法仅在Provider初始化时执行一次,后续你调用搜索接口获取到的新数据没有和Provider持有的状态绑定,也没有对应的机制通知UI重建。

推荐解决方案

这种需要主动触发数据刷新、支持搜索切换的场景,更适合用ChangeNotifierProvider替代FutureProvider,实现步骤如下:

1. 新增状态管理类

创建可通知状态变化的BillingDataNotifier,统一管理列表数据、加载状态和数据操作方法:

import 'package:flutter/foundation.dart';

class BillingDataNotifier extends ChangeNotifier {
  List<BillingData>? billingList;
  bool isLoading = false;
  final BillingDataService _service = BillingDataService();

  // 加载全量账单数据
  Future<void> loadFullBillingData() async {
    isLoading = true;
    notifyListeners();
    billingList = await _service.getBillingData();
    isLoading = false;
    notifyListeners();
  }

  // 执行搜索并更新列表
  Future<void> searchConcessionaire(String keyword) async {
    isLoading = true;
    notifyListeners();
    billingList = await _service.searchConcessionaire(keyword);
    isLoading = false;
    notifyListeners();
  }
}

2. 修改Provider注册逻辑

替换main.dart中的FutureProvider为ChangeNotifierProvider,初始化时自动加载全量数据:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => BillingDataNotifier()..loadFullBillingData(),
        ),
      ],
      child: MaterialApp(),
    );
  }
}

3. 修改列表页逻辑

在页面中消费BillingDataNotifier,搜索触发时调用对应的搜索方法即可自动刷新UI:

Widget build(BuildContext context) {
  final billingNotifier = context.watch<BillingDataNotifier>();
  return Scaffold(
    appBar: AppBar(
      // 搜索框示例,可根据需求替换为你的搜索触发逻辑
      title: TextField(
        onSubmitted: (value) {
          if (value.trim().isNotEmpty) {
            billingNotifier.searchConcessionaire(value.trim());
          } else {
            // 搜索词为空时恢复全量数据
            billingNotifier.loadFullBillingData();
          }
        },
        decoration: const InputDecoration(hintText: "搜索 concessions"),
      ),
    ),
    body: billingNotifier.isLoading || billingNotifier.billingList == null
        ? const Center(child: CircularProgressIndicator())
        : ListView.builder(
            itemCount: billingNotifier.billingList!.length,
            itemBuilder: (context, index) {
              final currentData = billingNotifier.billingList![index];
              return ConcessionaireCard(
                index: index,
                fullName: currentData.fullName,
                ctName: currentData.ctName,
                mtrNo: currentData.mtrNo,
                prevReading: currentData.prevReading,
                curReading: currentData.curReading,
              );
            }),
  );
}

如果你坚持使用FutureProvider的补充方案

如果不想更换Provider类型,可额外注册一个StateProvider存储搜索关键词,让FutureProvider依赖该关键词,每次关键词变更时自动重新执行Future拉取数据:

// 注册两个Provider
MultiProvider(
  providers: [
    StateProvider<String?>((ref) => null), // 存储搜索关键词
    FutureProvider<List<BillingData>>(
      create: (context) async {
        final keyword = context.watch<String?>();
        final service = BillingDataService();
        if(keyword == null || keyword.isEmpty) {
          return service.getBillingData();
        }
        return service.searchConcessionaire(keyword);
      },
    ),
  ],
  child: MaterialApp(),
)

搜索触发时更新StateProvider存储的关键词即可触发FutureProvider重新拉取数据、刷新UI。该方案适合简单场景,灵活度低于ChangeNotifier方案。


内容的提问来源于stack exchange,提问作者Valle John Teruel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 20:15:05