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,这应该不是什么大问题,但仍然…)感谢您的解决方案。同意转换是提高性能而不是重新绘制的更好方法。请分享您正在描述的小部件树的一个片段,好吗?我在实施你的解决方案时遇到困难。