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
相关产品推荐
相关产品推荐

