我创建了一个CustomPainter,可以绘制10000个元素的大画布。 包含此绘画者的CustomPaint被包裹在RepaintBoundary中。 问题:当我使用父窗口小部件的Transform.scale时,观察到fps变慢。 要进行缩放,请使用以下库:gesture_zoom_box
下面的代码段:
import 'package:flutter/material.dart';
import 'package:gesture_zoom_box/gesture_zoom_box.dart';
import 'dart:math';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: MyWidget(),
);
}
}
Map _generateData() {
final Map classes = {
"0": {"color": "#BF1C1C", "marker": "X"},
"1": {"color": "#F06D06", "marker": "Y"},
"2": {"color": "#B742C9", "marker": "Z"}
};
final rows = [];
final Random random = Random();
final List keys = List.from(classes.keys);
final listC = new List<int>.generate(100, (i) => i + 1);
final listR = new List<int>.generate(100, (i) => i + 1);
for (final _ in listR) {
final List row = [];
for (final _ in listC) {
row.add({"type": "box", "cls": keys[random.nextInt(keys.length)]});
}
rows.add(row);
}
final Map data = {
"map": {
"rows": rows
},
"cls": classes
};
return data;
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext ctx) {
final Map data = _generateData();
return Scaffold(
appBar: AppBar(
title: Text("MyApp")
),
body: GestureZoomBox(
child: LayoutBuilder(
builder: (ctx, constraints) {
final int rowsNum = data["map"]["rows"].length;
final int colsNum = data["map"]["rows"][0].length;
final double boxSide = min(constraints.maxWidth/colsNum, constraints.maxHeight/rowsNum);
final double width = boxSide * colsNum;
final double height = boxSide * rowsNum;
return Center(
child: Container(
width: width,
height: height,
child: RepaintBoundary(
child: CustomPaint(
painter: PixelGridPainter(data: data)
),
),
),
);
}
)
)
);
}
}
class PixelGridPainter extends CustomPainter {
final Map data;
PixelGridPainter({this.data});
@override
void paint(Canvas canvas, Size size) {
final rows = data['map']['rows'];
final cls = data['cls'];
final double boxSide = min(size.width/rows[0].length, size.height/rows.length);
final Paint paint = Paint();
paint.style = PaintingStyle.fill;
var i = 0;
for (final row in rows) {
final rowOffset = boxSide * i;
var j = 0;
for (final elem in row) {
final columnOffset = j * boxSide;
final Map elemCls = cls[elem['cls']];
final Color c = Color(int.parse(elemCls["color"].substring(1, 7), radix: 16) + 0xFF000000);
paint.color = c;
final rect = Rect.fromLTRB(columnOffset, rowOffset, columnOffset + boxSide, rowOffset + boxSide);
canvas.drawRect(
rect,
paint,
);
j += 1;
}
i += 1;
}
}
@override
bool shouldRepaint(PixelGridPainter old) {
return true;
}
}
我尝试PictureRecorder仅绘制图片并获得必要的60fps,但是我需要与此小部件进行快速交互,而如果不创建图像缓存则无法进行这种黑客攻击。 有人知道问题出在哪里吗?