如何从未来的构建器中监听多个提供商的变化?



我想显示一个条形图,其中我使用两个不同的提供程序作为源信息。

我最初的方法是使用未来的构建器,在获取数据时显示加载图标,然后操作该数据以满足我在图形中的需求。

因此,我使用了小部件中的未来构建器,在其中显示我的图形,并使用Future对其进行初始化,该将从另一个可重用文件中获取上下文。

my_wdiget.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)); // Simulation delayed query
var source1= Provider.of<MySource1>(context, listen: false).items;
var source2 = Provider.of<MySource2>(context, listen: false).otherItems;
List<MyObject> myObjects= [];
// Do some stuff to fill the myObjects using source1 and source2
return myObjects;  
}

问题:

  1. 这种工作,但我从提供商的行中得到警告use_build_context_synchronously
  2. 我想侦听更改,但是如果我设置了默认listen: true它将崩溃,告诉我更改该属性。

所以我的问题是,我怎样才能FutureBuilder监听多个提供商的变化?

建议使用方法进行更新@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 child: ElevatedButton(
child: Text('a'),
onPressed: test,
);
}
}
),
},
),

每次按下按钮时,它都会触发setState并且会出现circularProgressIndicator,尽管消费者没有进行任何更改。

要解决这两个问题,您可以使用Consumer2

如果两个提供程序中的任何一个发生更改,FutureBuilder将重新生成

Consumer2<MySource1, MySource1>(
builder: (context, sourceOne, sourceTwo, child) {
return FutureBuilder<List<MyObject>>(
future: myFutureVariable(sourceOne.items, sourceTwo.otherItems),
builder: (context, snapshot) {
// ...
}
),
},
),

并将函数更新为:

Future<List<MyObject>> getMyObjects(final items, final otherItems) async {
// use your items and otherItems here.
await Future.delayed(Duration(seconds: 1)); // just for testing, right?
List<MyObject> myObjects= [];
// Do some stuff to fill the myObjects using source1 and source2
return myObjects;  
}

相关内容

  • 没有找到相关文章