使用超过400个小盒子来优化可缩放网格

时间:2019-06-09 18:33:26

标签: flutter dart flutter-layout

我创建了带有可单击框的日历之类的东西,但是由于这些框很多,因此Android上的性能很差(iOS上没有此类问题)。 我正在使用以下代码来渲染整个事情:

ClipRect(
                          child: PhotoView.customChild(
                              customSize: Size(gridWidth, constraints.maxHeight),
                              child: GridView.builder(
                                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                                    crossAxisCount: 13,
                                    mainAxisSpacing: 1.0,
                                    crossAxisSpacing: 1.0,
                                    childAspectRatio: 1),
                                itemCount: gridCreationHelperClass.boxWidgets.length,
                                physics: ClampingScrollPhysics(),
                                padding: const EdgeInsets.all(4.0),
                                itemBuilder: (BuildContext context, int index) {
                                  return gridCreationHelperClass.boxWidgets[index];
                                },
                              ),
                              minScale: 1.0,
                              //initialScale: 5.0,
                              backgroundDecoration: BoxDecoration(
                                  color: Colors.transparent),
                              childSize: Size(gridWidth, constraints.maxHeight),
                              scaleChange: gridCreationHelperClass.scaleHasChanged,
                        )

这些boxWidgets可以是一个容器:

Container(
        alignment: AlignmentDirectional.center,
        color: color,
        child: Text(showTextInBox ? text : "", style: TextStyle(fontSize: textInBoxSize,color: Colors.white,
            fontFamily: getFontStatic(complexFont)), textAlign: TextAlign.center,)

或SVG:

Stack(children: <Widget>[
      new SvgPicture.asset(
        "images/squ.svg",
        color: color,

      ),
      Text(showTextInBox ? text : "", style: TextStyle(fontSize: textInBoxSize,color: Colors.white,
          fontFamily: getFontStatic(complexFont)), textAlign: TextAlign.center,)
    ],alignment: AlignmentDirectional.center)

还添加了放大文字,以便更轻松地查看日期。

您是否知道如何使其更快? 我当时正在考虑制作CustomPainter,但是我该如何使用它,它甚至会使事情变得更快?

屏幕截图:

Main Image

Zoomed in Container

Zoomed in SVG

我正在使用这些库:

//fork of
photo_view: ^0.4.0
flutter_svg: 0.13.0+1

谢谢您的帮助!

3 个答案:

答案 0 :(得分:1)

从未使用过photo_view库,但是可以肯定的是,您必须以某种方式缓存视图。

查看有关优化图形的帖子...它可能会起作用:

How to ensure my CustomPaint widget painting is stored in the raster cache?

答案 1 :(得分:0)

好吧,这仅在我的OnePlus 5T上才有问题,它在任何其他android手机(甚至是50美元的中文测试手机)和我在Android Jelly Bean上的原始Sony Xperia Z上都非常流畅地运行(仅使用Container,而不是SVG)。 我猜OnePlus太奇怪了。

目前我还放弃了整个GridView并构建了一个CustomPainter,即使在我的OP 5T + Debug上进行调试,它也可以稳定地以60 fps的速度进行缩放和滚动,这给了我很大的自由度,我不必担心未来的变化。

答案 2 :(得分:0)

因此,到目前为止,我采用了一种似乎表现出色的方法。完全不需要为此使用外部PhotoView依赖项。最好只将double _scale;添加到您的状态,然后使用Flutter内置的GestureDetector

GestureDetector(
  onScaleUpdate: (ScaleUpdateDetails scaleDetails) {
    setState(() {
      _scale = scaleDetails.horizontalScale;
    });
  },
  child: GridView.builder(
    gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: max(1, (16 / _scale).floor())),
    itemCount: _counter * 17,
    itemBuilder: (BuildContext context, int index) {
      return GridTile(
          child: SvgPicture.asset('assets/image.svg'));
    },
    padding: const EdgeInsets.all(4.0),
  ),
),

PhotoView docs似乎真的是针对可缩放/可缩放的照片-无论如何都不是您真正想要的网格布局。如果以上内容并非您所想要的,您可以通过在Container周围放置一些GridView并适当地使用您的状态,来实现您想要的。