Performance 颤振-更有效地平移和缩放自定义绘制
我正在渲染一组分片网格,其中每个分片都是从图像中提取的。为了呈现这一点,我在自己的Performance 颤振-更有效地平移和缩放自定义绘制,performance,flutter,Performance,Flutter,我正在渲染一组分片网格,其中每个分片都是从图像中提取的。为了呈现这一点,我在自己的CustomPainter实现中呈现所有内容(因为网格可能会变得相当大)。为了支持平移和缩放功能,我选择在画布绘制中执行偏移和缩放 这是我自定义绘画实现的一部分 @override void paint(Canvas canvas, Size size) { // With the new canvas size, we may have new constraints on min/max off
CustomPainter
实现中呈现所有内容(因为网格可能会变得相当大)。为了支持平移和缩放功能,我选择在画布绘制中执行偏移和缩放
这是我自定义绘画实现的一部分
@override
void paint(Canvas canvas, Size size) {
// With the new canvas size, we may have new constraints on min/max offset/scale.
zoom.adjust(
containerSize: size,
contentSize: Size(
(cellWidth * columnCount).toDouble(),
(cellHeight * rowCount).toDouble(),
),
);
canvas.save();
canvas.translate(zoom.offset.dx, zoom.offset.dy);
canvas.scale(zoom.scale);
// Now, draw the background image and grids.
虽然这是功能性的,但在渲染足够的单元格后,性能可能会开始崩溃(例如,100x100的网格会在更新缩放值的每个gesturedetor
回调上造成一些延迟)。而且,由于偏移和缩放是在CustomPaint
中完成的,我基本上不能为bool shouldRepaint(MyPainter old)
返回false,因为它需要重新绘制以呈现新的偏移和缩放
那么,我的问题是:解决这个问题更有效的方法是什么?
我尝试了另一种方法:
var separateRenderTree = RepaintBoundary(
child: OverflowBox(
child: CustomPaint(
painter: MyPainter(),
),
),
);
return Transform(
transform: Matrix4.translationValues(_zoom.offset.dx, _zoom.offset.dy, 0)..scale(_zoom.scale),
child: separateRenderTree,
);
这也是可行的,但在缩放时也会变慢(平移非常平滑)
那么,同样地,解决这个问题的正确方法是什么?
谢谢。这就是我的结局
我将自定义画师的大小调整为所需的大小,然后将其放置在Transform小部件中(左上角对齐,偏移量为零)
在这个小部件的顶部,我覆盖了一个管理触摸输入的不可见小部件。使用手势检测器,它将响应事件并通知转换小部件进行更新
随着平移/缩放功能正式移出画师,我随后实现了更严格的“shouldRepaint”功能
这使我能够以足够快的速度渲染非常非常大的网格。只需绘制那些可见的图像(我假设100x100个图像在同一时间不可见)这在大多数情况下都有效,但用户可以缩小到足以查看整个网格的程度。我目前的逻辑只在可视视口中绘制它的图像,但性能增益不够好。在一个屏幕上显示100x100网格有什么意义?这些图像的大小可能是10到20像素……因为是Flutter,我不仅仅局限于移动设备。我计划在网上使用这个。100x100并非不切实际。您是否在每个帧上创建全新的CustomPaint
?(如果您的CustomPainter
在其ctor中没有消耗太多cpu,这应该不是什么大问题,但仍然…)感谢您的解决方案。同意转换是提高性能而不是重新绘制的更好方法。请分享您正在描述的小部件树的一个片段,好吗?我在实施你的解决方案时遇到困难。