Flutter如何实现类iOS图片多选的拖拽框选网格交互效果
Flutter 实现类iOS网格拖拽多选交互方案
一、基于GestureDetector的实现方法
- 首先提前存储所有网格tile的位置信息:给每个tile绑定GlobalKey,在页面首次渲染完成后,通过GlobalKey获取每个tile对应在全局坐标系中的
Rect区域,统一存到数组中,关联好tile索引和位置范围的映射关系。 - 给整个网格的父容器包裹GestureDetector,监听拖拽手势的三个核心回调:
onPanStart:记录手势按下的起始坐标,匹配起始坐标落在哪个tile上,标记该tile为本次框选的起始点,同时初始化当前选区的范围。onPanUpdate:实时获取手势拖拽的当前坐标,用起始点和当前点计算出完整的选区矩形,遍历所有tile的Rect,只要和选区矩形存在重叠就标记为选中状态,局部刷新网格的选中状态即可。onPanEnd:拖拽结束后锁定当前选中的tile列表,完成本次多选操作。
- 如果需要支持网格滚动时的跨区域框选,额外监听网格的滚动偏移,计算选区坐标时同步扣除滚动偏移量,避免坐标匹配错位。
核心判断逻辑示例:
// 校验单个tile是否在当前选区内 bool checkTileSelected(Rect tileRect, Rect selectionRect) { return tileRect.overlaps(selectionRect); }
二、通过Canvas绘制矩形实现的可行性
可以实现,而且性能表现更好,实现逻辑如下:
- 在网格的最上层叠加一个自定义的CustomPaint组件,用于绘制拖拽过程中的半透明选区框和边框。
- 拖拽过程中每次更新选区范围时,把最新的选区Rect传给CustomPainter,在paint方法中调用
canvas.drawRect()直接绘制选区,不需要重绘所有网格tile,只需要刷新CustomPaint的绘制内容即可,资源消耗更低。 - 绘制时注意把手势的全局坐标转换为CustomPaint自身的局部坐标,避免出现选区位置偏移的问题。
内容的提问来源于stack exchange,提问作者kodaira
相关产品推荐
相关产品推荐

