一个图片编辑板,有两部分组成。编辑板和内容项。每一个内容项是被InteractiveViewer修饰的widget,具有缩放偏移的功能。
在图片编辑板上, 会有多个内容相,图片或文字(添加文字目前还没做过)。 当要编辑其中一个项目时,必然需要先选中这个项目。这就牵扯到事件问题。是不是点中哪个看到的项目,这个项目就会发出事件?实际情况是不会的。因为InteractiveViewer的大小是覆盖真个编辑板的,虽然看到的内容项小,其实是占用了所有编辑板的。这就导致事件无法传递给你看到并点击的内容项。
这就需要我们重新实现编辑板的事件路由。
-
我们在InteractiveViewer再修饰一层GestureDetector。这样就能获取在编辑板上点击的所有事件!
-
实时计算每一个内容项的事件区域,或者说在编辑板所占位置大小,也就是一个Rect对象。这里要注意缩放问题。
Dart
if (widget.transformationController != null &&
widget.mergeItemInfo.eventArea != null) {
double transX = widget.transformationController!.value
.getTranslation()
.x; //the distance in UI review.
double transY = widget.transformationController!.value.getTranslation().y;
double scale = widget.transformationController!.value.getMaxScaleOnAxis();
Rect eventArea = Rect.fromLTWH(
widget.mergeItemInfo.initEventArea!.left * scale + transX,
widget.mergeItemInfo.initEventArea!.top * scale + transY,
widget.mergeItemInfo.initEventArea!.width * scale,
widget.mergeItemInfo.initEventArea!.height * scale);
widget.mergeItemInfo.eventArea = eventArea;
}
- 根据点击的事件位置,路由的遍历每一个内容项,查看是否命中,命中就返回事件给这个内容项。
Dart
bool isInEventArea(TapDownDetails details) {
Offset point = details.localPosition;
if (eventArea != null) {
return point.dx >= eventArea!.left &&
point.dx <= eventArea!.left + eventArea!.width &&
point.dy >= eventArea!.top &&
point.dy <= eventArea!.top + eventArea!.height;
}
return false;
}