const / static / final CustomPainter和CustomClipper实现

时间:2019-06-20 17:12:56

标签: flutter dart

在提供者软件包的作者Remi Rousselet提出并回答的问题How to deal with unwanted widget build 中,它说在类构造函数前面使用const有助于避免不必要的小部件构建。

我的CustomPainterCustomClipper遇到性能问题,并希望应用此策略。我的CustomClipper裁剪了具有特定自定义形状的子窗口小部件,而我的CustomPainter根据所裁剪的形状边界绘制了阴影。 这两个形状完全不变。子Text叶小部件内部只有可变对象。 Text的字符串和长度对自定义剪切器和画笔的形状没有影响。

shouldRepaintshouldReclip返回false。

问题是我该如何使这两个类为const或static,以便在允许Text小部件随其构建更改其内容的同时,不使它们的父小部件在每次构建时都进行重建?您还能想到其他任何方法来删除不需要更改的窗口小部件吗?

要深入了解我正在构建的内容:我在世界地图上有多个Flutter_Map标记作为小部件。这些标记具有自定义的裁剪形状和自定义的阴影以及边界形状。在这个自定义形状的内部,我有一个Marquee Text小部件,它从FireStore获取其值。

此选取框具有动画效果(例如,文本行情指示器左右移动,以使整个句子的宽度只有几个像素)。

标记大小绝对不会改变。但是我平移了地图,它们的坐标在屏幕上改变了。

single_marker_widget.dart

class SingleMarkerWidget extends StatefulWidget {
  final Table table;  //filleduchaos this is where I pass the Text widgets string
  const SingleMarkerWidget({Key key, this.table}) : super(key: key);
  @override
  _SingleMarkerWidgetState createState() => _SingleMarkerWidgetState();
}

class _SingleMarkerWidgetState extends State<SingleMarkerWidget> {
  @override
  Widget build(BuildContext context) {
    return ClipShadowPath(
      clipper: _SingleMarkerClipper(),
      shadow: Shadow(
        color: Colors.grey[800],
        blurRadius: 25,
        offset: Offset(5.0, 8.0),
      ),
      child: RepaintBoundary(
        child: Marquee(
          textList: [
            widget.table.tableGame.gameName,
            widget.table.tableVenue.venueName,
            widget.table.tableVenue.venueDistrict,
          ],
        ),
      ),
    );
  }
}

class _SingleMarkerClipper extends CustomClipper<Path> {
  @override
  getClip(Size size) {
    print(
        '_SingleMarkerClipper ==== getClip'); //1- THIS PRINT PRINTS WAY TOO OFTEN. THIS IS WHAT I AM TRYING TO GET RID OF.
    //....
    //DRAW THE CUSTOM SHAPE
    //....
    return path;
  }

  @override
  bool shouldReclip(CustomClipper oldClipper) {
    return false;
  }
}

clip_shadow_path.dart

@immutable
class ClipShadowPath extends StatelessWidget {
  final Shadow shadow;
  final CustomClipper<Path> clipper;
  final Widget child;

  const ClipShadowPath({
    @required this.shadow,
    @required this.clipper,
    @required this.child,
  });

  @override
  Widget build(BuildContext context) {
    print('ClipShadowPath ==== build');
    return CustomPaint(
      painter: _ClipShadowShadowPainter(
        clipper: this.clipper,
        shadow: this.shadow,
      ),
      child: ClipPath(child: this.child, clipper: this.clipper),
    );
  }
}

class _ClipShadowShadowPainter extends CustomPainter {
  final Shadow shadow;
  final CustomClipper<Path> clipper;

  const _ClipShadowShadowPainter(
      {@required this.shadow, @required this.clipper});

  @override
  void paint(Canvas canvas, Size size) {
    print(
        '_ClipShadowShadowPainter ==== paint'); //2- THIS PRINT PRINTS WAY TOO OFTEN. THIS IS WHAT I AM TRYING TO GET RID OF.
    var paint = shadow.toPaint();
    var clipPath = clipper.getClip(size).shift(shadow.offset);
    canvas.drawPath(clipPath, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

0 个答案:

没有答案