如何从dart中的异步数据中提取?

时间:2018-03-06 13:36:31

标签: mobile dart flutter

我试图读取文件(异步)并返回数据列表。然后,我想使用CustomPainter(我想绘制多行)每个给定数字是行高时绘制线条

class BarChartPainter extends CustomPainter {
  @override
  paint(Canvas canvas, Size size) {
    final paint = new Paint()
      ..color = AppColors.primaryColor
      ..style = PaintingStyle.fill;

    var futurePath = run();

    futurePath.then((height) {
      print('1: $height');
      for (var lineHeight in height) {
        print('2: $lineHeight');
        canvas.drawRect(
            new Rect.fromLTWH(1.0, 10.0, 10.0, lineHeight.toDouble()), paint);
      }
    }).catchError((e) => print(e));
  }

  @override
  bool shouldRepaint(BarChartPainter old) => false;
}

print(' 1:$ height')返回[75,0,0,0,0,0,0,0,0,06,72,10,2,0,0] ,0,0,0,(...),0,85,22,3,1]

打印(' 2:$ lineHeight')返回75

drawRect不起作用。错误是:I / flutter(13751):对象已被处理。

1 个答案:

答案 0 :(得分:2)

绘制帧时,所有数据都需要准备好。在这种情况下使用Future意味着数据仅在渲染画布后才可用。

处理此问题的一种方法是将文件加载移动到CustomPainter之外,并在加载数据时渲染画家。这是从JSON资产文件加载的示例:

    class BarChart extends StatefulWidget {
    @override
    createState() => new BarChartState();
    }

    class BarChartState extends State<BarChart> {
    var barHeights = <int>[];

    @override
    initState() {
        super.initState();
        _fetchBarHeights();
    }

    _fetchBarHeights() async {
        final heights = await rootBundle
            .loadStructuredData<List<int>>('assets/barchart.json', (jsonStr) async {
        final jsonList = json.decode(jsonStr);
        return (jsonList as List).map((i) => (i as int)).toList();
        });
        setState(() => barHeights = heights);
    }

    @override
    Widget build(BuildContext context) {
        return new Center(
            child: new CustomPaint(
        painter: new BarChartPainter(barHeights),
        ));
    }
    }

    class BarChartPainter extends CustomPainter {
    BarChartPainter(this.barHeights);
    final List<int> barHeights;

    @override
    paint(Canvas canvas, Size size) {
        final paint = new Paint()
        ..color = Colors.blue
        ..style = PaintingStyle.fill;

        var pos = 0.0;
        barHeights.forEach((barHeight) {
            canvas.drawRect(
                new Rect.fromLTWH(pos, 10.0, 10.0, barHeight.toDouble()),
                paint,
            );
            pos += 10;
        });
    }

    @override
    bool shouldRepaint(BarChartPainter old) =>
        !(new ListEquality().equals(old.barHeights, barHeights));
    }