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

如何在特定区域处理鼠标事件:六边形蜂窝组件点击问题

Flutter蜂窝组件中六边形精准点击的实现方案

完全可行,核心是通过自定义组件的命中测试(hit test),让系统只把六边形内部区域判定为可点击区域,外部的点击会自动穿透到底层组件处理。

具体实现步骤:

  • 第一步:在Hexagon组件中保存绘制用的六边形Path对象
    因为CustomPainter绘制的路径仅在paint方法内可用,所以需要把路径传递给外层的Hexagon组件保存,方便后续做命中判断。
  • 第二步:重写Hexagon组件的hitTest方法
    Flutter组件默认用自身矩形边界做命中判断,我们要重写这个方法,仅当点击点落在六边形路径内部时返回true,否则返回false,这样触摸事件会继续向下传递给底层组件。
  • 第三步:配合GestureDetector使用
    给Hexagon加上GestureDetector后,只有hitTest返回true时,才会触发onTap回调。

以下是简化的代码示例:

import 'dart:math';
import 'package:flutter/material.dart';

class Hexagon extends StatelessWidget {
  final double size;
  final Color color;
  final VoidCallback? onTap;
  Path? _hexPath;

  Hexagon({required this.size, required this.color, this.onTap});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: CustomPaint(
        // 正六边形实际尺寸:宽为size,高为size*√3/2
        size: Size(size, size * sqrt(3) / 2),
        painter: _HexPainter(
          color,
          onPathGenerated: (path) => _hexPath = path,
        ),
      ),
    );
  }

  @override
  bool hitTest(Offset position) {
    // 仅点击点在六边形路径内时,才判定为命中
    return _hexPath?.contains(position) ?? false;
  }
}

class _HexPainter extends CustomPainter {
  final Color color;
  final void Function(Path) onPathGenerated;

  _HexPainter(this.color, {required this.onPathGenerated});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = color;
    final path = Path();
    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width / 2;
    const angleStep = 2 * pi / 6; // 正六边形每个边对应的圆心角

    // 生成六边形路径
    for (int i = 0; i < 6; i++) {
      final angle = i * angleStep - pi / 2; // 起始角度向上对齐
      final x = center.dx + radius * cos(angle);
      final y = center.dy + radius * sin(angle);
      i == 0 ? path.moveTo(x, y) : path.lineTo(x, y);
    }
    path.close();

    // 将路径传递给外层组件
    onPathGenerated(path);
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(_HexPainter oldDelegate) {
    return oldDelegate.color != color;
  }
}

这样处理后,点击六边形外部的矩形区域时,当前Hexagon的hitTest返回false,触摸事件会继续向下传递给底层的六边形组件;只有点击六边形内部时,才会触发当前组件的点击回调。

内容的提问来源于stack exchange,提问作者Marc Van Daele

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:55:24