GestureDetector组件
GestureDetector(
child: Container( // 除了GestureDetector,还需要Transform.translate和Transform.scale两个组件来控制位置和scale
child: Transform.translate(
key: imagekey,
offset: Offset(dx, dy),
child: Transform.scale(
scale: picScale, child: Image(
image: AssetImage("images/test.png")
)
)
)
),
// 在这里监听手势处理
onScaleStart: (d) { // 缩放事件开始前现在这个事件中获取初始坐标
_lastOffset = d.focalPoint;
},
// 监听缩放事件和拖拽
onScaleUpdate: (ScaleUpdateDetails details) {
// 这里的0.98和1.02控制details.scale的最大最小值,从而控制缩放速度
double tempScale = picScale * details.scale.clamp(0.98, 1.02);
double tempDx = dx + details.focalPoint.dx - _lastOffset.dx;
double tempDy = dy + details.focalPoint.dy - _lastOffset.dy;
// 这里是缩放和拖拽的处理,属于算法层面的东西,我算法不行,写得很乱
// 大概情况就是控制缩放区间为[0.7,3.5],拖拽和缩放时控制图片的位置,不能消失在屏幕,然后还有双指水平滑动会触发缩放的bug解决
if (tempScale <= 3.5 && tempScale >= 1) {
if (tempDx.abs() < screenWidth * (tempScale - 1) / 2) {
dx = tempDx;
} else {
dx = dx > 0 ? screenWidth * (tempScale - 1) / 2 - 1 : -(screenWidth * (tempScale - 1) / 2 - 1);
}
if (tempDy.abs() < screenHeight * (tempScale - 1) / 2) {
dy = tempDy;
} else {
dy = dy > 0 ? screenHeight * (tempScale - 1) / 2 - 1 : -(screenHeight * (tempScale - 1) / 2 - 1);
}
// details.verticalScale是多指操作时相对垂直平分线移动的距离比例,可用于检测多指平行滑动
if ((1 - details.verticalScale).abs() > 0.28) {
picScale = tempScale;
}
}
// 可以缩小到比原图小,但是不能移动
if (tempScale < 1 && tempScale >= 0.7 && (1 - details.verticalScale).abs() > 0.28) {
picScale = tempScale;
}
_lastOffset = details.focalPoint;
setState(() {}); // **注意dx,dy和scale都是声明在state里的,一定要setState才会生效**
},
// 监听移动事件, 由于onScaleUpdate已经包含了移动,在有onScaleUpdate的情况下不能监听下面两个事件
// onHorizontalDragUpdate: dragEvent,
// onVerticalDragUpdate: dragEvent,
// 双击事件,处理为还原
onDoubleTap: () {
setState(() {
picScale = 1.0;
dx = 0.0;
dy = 0.0;
});
}
)
- 但是结果虽然功能都实现了,但是体验不是很好,使用不是很顺畅,大概是我算法的问题,但是总体思路有就行了