You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让CustomPaint的子Icon居中对齐自定义绘制的六边形?

问题根源

CustomPaint的子组件不会自动适配你在Painter中自定义绘制的图形位置,你手动指定六边形的中心为Offset(100,100),但Icon默认对齐CustomPaint组件的左上角,因此出现错位。

解决方案

推荐优先采用适配CustomPaint尺寸的方案,无需硬写坐标,适配性更强:

第一步:修改HexagonPainter代码

优化中心点计算逻辑,优先使用CustomPaint自身的尺寸计算中心,避免硬传坐标:

import 'dart:math' as math;

class HexagonPainter extends CustomPainter {
  static const int SIDES_OF_HEXAGON = 6;
  final double radius;
  final Offset? center;

  HexagonPainter({this.center, required this.radius});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()..color = const Color(0xff05c2c9);
    // 未传入center时默认取CustomPaint自身的中心点
    final actualCenter = center ?? Offset(size.width / 2, size.height / 2);
    Path path = createHexagonPath(actualCenter);
    canvas.drawPath(path, paint);
  }

  Path createHexagonPath(Offset center) {
    final path = Path();
    var angle = (math.pi * 2) / SIDES_OF_HEXAGON;
    Offset firstPoint = Offset(radius * math.cos(0.0), radius * math.sin(0.0));
    path.moveTo(firstPoint.dx + center.dx, firstPoint.dy + center.dy);
    for (int i = 1; i <= SIDES_OF_HEXAGON; i++) {
      double x = radius * math.cos(angle * i) + center.dx;
      double y = radius * math.sin(angle * i) + center.dy;
      path.lineTo(x, y);
    }
    path.close();
    return path;
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

第二步:修改调用代码

给CustomPaint套固定尺寸的SizedBox,用Center包裹Icon即可实现自动居中:

SizedBox(
  // 宽高设为2倍半径,刚好完整容纳六边形
  width: 130,
  height: 130,
  child: CustomPaint(
    painter: HexagonPainter(radius: 65),
    child: const Center(
      child: Icon(Icons.speed, color: Colors.white, size: 40),
    ),
  ),
)

零侵入替代方案(无需修改HexagonPainter)

如果不想改动原有Painter代码,只要用Stack+Positioned把Icon定位到六边形中心位置即可:

const double iconSize = 40;
SizedBox(
  width: 200,
  height: 200,
  child: CustomPaint(
    painter: HexagonPainter(center: const Offset(100, 100), radius: 65),
    child: Stack(
      children: [
        Positioned(
          // Icon左上角偏移 = 六边形中心坐标减去Icon自身尺寸的一半
          left: 100 - iconSize / 2,
          top: 100 - iconSize / 2,
          child: Icon(Icons.speed, color: Colors.white, size: iconSize),
        )
      ],
    ),
  ),
)

内容的提问来源于stack exchange,提问作者MhdBasilE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 11:42:02