所以我试图使用fl_chart插件显示一个饼图。该图表的数据正在从Firestore中检索。我有用于显示数据的此函数:
List<PieChartSectionData> showSection(AsyncSnapshot<QuerySnapshot> snapshot) {
return List.generate(length, (i) {
final isTouched = i == touchedIndex;
final double fontSize = isTouched ? 25 : 16;
final double radius = isTouched ? 60 : 50;
return PieChartSectionData(
color: Color(int.parse(cerealData[i].colorVal)),
value: cerealData[i].rating,
title: cerealData[i].rating.toString(),
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
);
});
}
List.generate()接受一个int作为参数。由于我正在显示实时数据,因此我尝试获取集合中存在的文档数。为此,我有一个名为getLength()的函数:
void getLength(AsyncSnapshot<QuerySnapshot> snapshot) async {
length = await Firestore.instance.collection('cereal').snapshots().length;
cerealData =
snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList();
}
但是,当我运行代码时,得到:
Another exception was thrown: type 'Future<int>' is not a subtype of type 'int'
整个代码:
class _FlChartPageState extends State<FlChartPage> {
int touchedIndex;
var length;
List<Cereal> cerealData;
void getLength(AsyncSnapshot<QuerySnapshot> snapshot) async {
length = await Firestore.instance.collection('cereal').snapshots().length;
cerealData =
snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('cereal').snapshots(),
builder: (context, snapshot) {
getLength(snapshot);
if (!snapshot.hasData)
return CircularProgressIndicator();
else {
return PieChart(PieChartData(
pieTouchData: PieTouchData(touchCallback: (pieTouchResponse) {
setState(() {
if (pieTouchResponse.touchInput is FlLongPressEnd ||
pieTouchResponse.touchInput is FlPanEnd) {
touchedIndex = -1;
} else {
touchedIndex = pieTouchResponse.touchedSectionIndex;
}
});
}),
borderData: FlBorderData(show: false),
sectionsSpace: 0,
centerSpaceRadius: 40,
sections: showSection(snapshot)));
}
}),
);
}
List<PieChartSectionData> showSection(AsyncSnapshot<QuerySnapshot> snapshot) {
return List.generate(length, (i) {
final isTouched = i == touchedIndex;
final double fontSize = isTouched ? 25 : 16;
final double radius = isTouched ? 60 : 50;
return PieChartSectionData(
color: Color(int.parse(cerealData[i].colorVal)),
value: cerealData[i].rating,
title: cerealData[i].rating.toString(),
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
);
});
}
}
我在某处读到,等待未来摆脱了未来。但这在这里不起作用。我该如何解决?
编辑:如果我只是传递文档数而不是传递List.generate()中的长度,它将起作用。但是,如果对集合进行了更改,这将无法正常工作。那么,如何将Future转换为int?
因此您不一定需要将快照作为参数传递给调用
length =等待Firestore.instance.collection('cereal')。snapshots()。length;
所以像在initState()之类那样在streamBuilder之外的地方调用它,并使用setState()从那里设置长度,例如
getLength()async{
int lengthA = await Firestore.instance.collection('cereal').snapshots().length;
setState(() {
this.length = lengthA;
});
}
对于list.generate,您必须等待加载的长度才能显示,因此请检查lenght是否为null,如
List<PieChartSectionData> showSection(AsyncSnapshot<QuerySnapshot> snapshot) {
return (length==null)
?Container()//show empty container until it loads the length
:List.generate(length, (i) {
final isTouched = i == touchedIndex;
final double fontSize = isTouched ? 25 : 16;
final double radius = isTouched ? 60 : 50;
return PieChartSectionData(
color: Color(int.parse(cerealData[i].colorVal)),
value: cerealData[i].rating,
title: cerealData[i].rating.toString(),
radius: radius,
titleStyle: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.bold,
color: const Color(0xffffffff)),
);
});
}
在get getLength函数中,您试图获取长度,这实际上是一个异步任务,该任务会返回将来,因此,您将得到以下错误。
使用以下方法更改您的方法
getLength()async{
Firestore.instance.collection('cereal').snapshots().length.then((len){
length = len;
cerealData =
snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList();
});
}