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

Flutter中如何在图片的点击位置绘制彩色圆点?

解决方案

你现在拿到的是全局坐标,直接用会因为父容器的margin、布局偏移导致圆点位置不对,得先把全局坐标转成图片容器的本地坐标,再用Stack组件把圆点叠加在图片上。下面是完整实现:

核心思路

  • 用列表存储所有点击坐标,支持添加多个圆点
  • 通过RenderBox将全局坐标转换为图片容器内的本地坐标
  • 用Stack包裹图片和圆点,通过Positioned定位每个圆点

完整代码

import 'package:flutter/material.dart';

class ImageTapDotPage extends StatefulWidget {
  const ImageTapDotPage({super.key});

  @override
  State<ImageTapDotPage> createState() => _ImageTapDotPageState();
}

class _ImageTapDotPageState extends State<ImageTapDotPage> {
  // 存储所有点击的坐标点
  final List<Offset> _tapPoints = [];
  // 图片容器的key,用来获取渲染对象做坐标转换
  final GlobalKey _imageContainerKey = GlobalKey();

  void gettingPosition(TapDownDetails details) {
    // 获取图片容器的RenderBox对象
    final RenderBox renderBox = _imageContainerKey.currentContext!.findRenderObject() as RenderBox;
    // 把全局坐标转换成容器内的本地坐标
    final Offset localOffset = renderBox.globalToLocal(details.globalPosition);
    
    setState(() {
      _tapPoints.add(localOffset);
    });
    print("本地坐标: ${localOffset.dx}, ${localOffset.dy}");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("点击图片加圆点")),
      body: Center(
        child: Stack(
          children: [
            GestureDetector(
              onTapDown: gettingPosition,
              child: Container(
                key: _imageContainerKey,
                margin: const EdgeInsets.only(left: 8, right: 8),
                height: 300,
                width: double.infinity,
                child: Image.network(
                  "https://w0.peakpx.com/wallpaper/300/911/HD-wallpaper-dark-vertical-black.jpg",
                  fit: BoxFit.cover,
                ),
              ),
            ),
            // 遍历所有点击点,生成圆点
            ..._tapPoints.map((offset) {
              return Positioned(
                left: offset.dx - 5, // 圆点半径5,向左偏移5让中心对齐点击位置
                top: offset.dy - 5,
                child: Container(
                  width: 10,
                  height: 10,
                  decoration: const BoxDecoration(
                    color: Colors.red, // 替换成你需要的任意颜色
                    shape: BoxShape.circle,
                  ),
                ),
              );
            }),
          ],
        ),
      ),
    );
  }
}

关键细节

  • GlobalKey用来精准获取图片容器的渲染信息,保证坐标转换没有偏差
  • 给Positioned的left和top减去圆点半径,能让圆点中心正好落在点击位置
  • 如果需要支持删除圆点,给每个圆点加点击事件,从_tapPoints列表中移除对应元素即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:32:21