You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让FutureBuilder监听多个Provider的状态变化?

问题:如何让FutureBuilder监听多个Provider的变化?

场景与初始实现

我需要展示一个BarChart,其数据源来自两个不同的Provider。初始方案是用FutureBuilder:获取数据时显示加载图标,处理完数据后适配图表需求。在展示图表的Widget中使用FutureBuilder,通过一个复用文件中的Future初始化。

my_widget.dart 代码

...
class _MyWidgetState extends State<MyWidget> {
  late Future<List<MyObject>> myFutureVariable;

 Future<List<MyObject>> _getMyObjects() async {
    return getMyObjects(context);
  }

  @override
  void initState() {
    super.initState();
    myFutureVariable= _getMyObjects();
  }

...


FutureBuilder<List<MyObject>>(
                future: myFutureVariable,
                builder: (BuildContext context,
                    AsyncSnapshot<List<MyObject>> snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.waiting:
                      return Center(child: CircularProgressIndicator()),
                  
                      );
                    default:
                      if (snapshot.hasError) {
                        return Center(
                                    child: Text('Error: ${snapshot.error}'))),

                        );
                      } else if (snapshot.data == null) {
                        return Center(
                                    child:
                                        Text('You don\'t have any item yet.'))),
                        );
                      } else {
                        return BarChart(
                            _getChartData(snapshot.data!),
                          ),
                        );
                      }
                  }
                },
              ),

my_object_utils.dart 代码

Future<List<MyObject>> getMyObjects(BuildContext context) async {
  await Future.delayed(Duration(seconds: 1)); // 模拟延迟请求
  var source1= Provider.of<MySource1>(context, listen: false).items;
  var source2 = Provider.of<MySource2>(context, listen: false).otherItems;
  List<MyObject> myObjects= [];
  // 处理source1和source2,填充myObjects
  return myObjects;  
}

遇到的问题

  • 代码可正常运行,但Provider相关代码行出现use_build_context_synchronously警告
  • 想要监听Provider的变化,但设置默认的listen: true会导致崩溃,提示修改该属性

更新后新问题

采用@hydra建议的方案后,使用如下代码:

void test() {
    print('a');
    setState(() {});
  }

Consumer2<MySource1, MySource1>(
  builder: (context, sourceOne, sourceTwo, child) {
    myFutureVariable = getMyObjects(sourceOne.items, sourceTwo.otherItems),
    return FutureBuilder<List<MyObject>>(
      future: myFutureVariable,
      builder: (context, snapshot) {
          ... 
           else{
             return ElevatedButton(
                                child: Text('a'),
                                onPressed: test,
                              );
      }
      }
    ),
  },
),

每次点击按钮触发setState时,即使Consumer监听的Provider没有变化,CircularProgressIndicator仍会出现。

内容的提问来源于stack exchange,提问作者nck

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:15:53