我试图读取文件(异步)并返回数据列表。然后,我想使用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):对象已被处理。
答案 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));
}