【问题标题】:type 'Future<List<ChartSeries<BarChartModel, String>>>' is not a subtype of type 'List<ChartSeries<dynamic, dynamic>>'type 'Future<List<ChartSeries<BarChartModel, String>>>' 不是类型 'List<ChartSeries<dynamic, dynamic>>' 的子类型
【发布时间】:2022-01-18 11:21:21
【问题描述】:

我在 Flutter 中使用 Firestore 和 Syncfusion Flutter Charts 时遇到问题。 我正在从 firestore 查询一些文档,等待结果,所以函数必须是 Future,但我需要它是 List,而不是 Future&lt;List&gt;。这是我的代码:

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: SfCartesianChart(
        primaryXAxis: CategoryAxis(
          majorGridLines: const MajorGridLines(width: 0),
          axisLine: const AxisLine(width: 0),
        ),
        primaryYAxis: NumericAxis(
          majorGridLines: const MajorGridLines(width: 0),
          axisLine: const AxisLine(width: 0),
        ),
        plotAreaBorderWidth: 0,
        series: getData(),
      ),
    );
  }

  String getcurrentMonth() {
    DateTime date = DateTime.now();
    return DateFormat.MMMM().format(date).substring(0, 3);
  }

  List<String> getOtherMonths() {
    List<String> otherMonths = [];
    DateTime date = DateTime.now();
    for (var i = 1; i < 5; i++) {
      DateTime prev = DateTime(date.year, date.month - i, date.day);
      otherMonths.add(DateFormat.MMMM().format(prev).substring(0, 3));
    }
    return otherMonths;
  }

  Future<List<double>> getTotalByMonth() async {
    List<double> totals = [];
    DateTime date = DateTime.now();
    for (var i = 0; i < 5; i++) {
      var lastDay = DateTime(date.year, date.month - i + 1, 0);
      DateTime startOfMonth = DateTime(date.year, date.month - i, 1);
      DateTime endOfMonth =
          DateTime(date.year, date.month - i, lastDay.day, 23, 59, 59, 999);
      Timestamp startTimestamp = Timestamp.fromDate(startOfMonth);
      Timestamp endTimestamp = Timestamp.fromDate(endOfMonth);
      await FirebaseFirestore.instance
          .collection('users/$uid/receipts')
          .where('date', isGreaterThanOrEqualTo: startTimestamp)
          .where('date', isLessThanOrEqualTo: endTimestamp)
          .get()
          .then((doc) {
        double monthTot = 0;
        doc.docs.forEach((element) {
          monthTot += element.data()['total'];
        });
        totals.add(monthTot);
      });
    }
    return totals;
  }

  Future<List<ChartSeries<BarChartModel, String>>> getData() async {
    String currentMonth = getcurrentMonth();
    List<String> months = getOtherMonths();
    months.insert(0, currentMonth);
    months = months.reversed.toList();
    List<double> totals = await getTotalByMonth();
    List<BarChartModel> data = [];
    for (var i = 0; i < 5; i++) {
      var obj = BarChartModel(months[i], totals[i],
          i % 2 == 0 ? const Color(0xff003f9a) : const Color(0xff468fea));
      data.add(obj);
    }
    return <ChartSeries<BarChartModel, String>>[
      ColumnSeries<BarChartModel, String>(
        dataSource: data,
        xValueMapper: (BarChartModel data, _) => data.month,
        yValueMapper: (BarChartModel data, _) => data.total,
        pointColorMapper: (BarChartModel data, _) => data.month == currentMonth
            ? const Color(0xffeaa146)
            : data.barColor,
        animationDuration: 1000,
        borderRadius: const BorderRadius.only(
          topRight: Radius.circular(5),
          topLeft: Radius.circular(5),
        ),
      ),
    ];
  }

这是模型:

class BarChartModel {
  final String month;
  final double total;
  final Color barColor;

  BarChartModel(this.month, this.total, this.barColor);
}

这是我重新加载应用时遇到的错误:

type 'Future<List<ChartSeries<BarChartModel, String>>>' is not a subtype of type 'List<ChartSeries<dynamic, dynamic>>'

在这种情况下,摆脱 Future 类型的最佳方法是什么?

【问题讨论】:

    标签: flutter asynchronous google-cloud-firestore syncfusion syncfusion-chart


    【解决方案1】:

    FutureBuilder 小部件将在这里提供帮助。

    查看https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html 了解如何使用 FutureBuilder。

    基本思路:FutureBuilder 会加载你想要展示的数据。在加载过程中,您将显示一个进度指示器。加载完成后可以显示数据,这将不再是未来,而是实际数据。

    【讨论】:

    • 非常感谢!它就像一个魅力!
    【解决方案2】:

    我们从我们这边分析了您的查询,我们建议您使用 FutureBuilder,因为它基于与 Future 交互的最新快照构建自己。我们在下面提供了代码 sn-p 供您参考,您可以根据自己的需要进行修改。

    代码sn-p:

    late Future<List<ChartSeries<BarChartModel, String>>> chartData;
    
     
    
      @override
    
      void initState() {
    
        chartData = getData();
    
        super.initState();
    
      }
    
     
    
      @override
    
      Widget build(BuildContext context) {
    
        return FutureBuilder(
    
            future: chartData,
    
            builder: (context, snapshot) {
    
              if (snapshot.hasData) {
    
                return SfCartesianChart(
    
                  primaryXAxis: CategoryAxis(
    
                    majorGridLines: const MajorGridLines(width: 0),
    
                    axisLine: const AxisLine(width: 0),
    
                  ),
    
                  primaryYAxis: NumericAxis(
    
                    majorGridLines: const MajorGridLines(width: 0),
    
                    axisLine: const AxisLine(width: 0),
    
                  ),
    
                  plotAreaBorderWidth: 0,
    
                  series: snapshot.data,
    
                );
    
              } else if (snapshot.hasError) {
    
                return const Text('Something went wrong');
    
              } else {
    
                return const CircularProgressIndicator();
    
              }
    
            });
    
      }
    
    

    【讨论】:

      猜你喜欢
      • 2019-01-26
      • 2019-05-02
      • 2021-01-22
      • 2021-12-29
      • 2023-01-08
      • 2019-09-02
      • 2019-06-26
      • 2020-09-20
      • 1970-01-01
      相关资源
      最近更新 更多