[英]Android rotate view around dynamic pivot
我正在开发一个ViewGroup布局,该布局能够检测触摸事件并根据触摸事件缩放/旋转/平移其子视图。 我的问题是我希望孩子围绕用户手指两根手指之间的点旋转/缩放, 而不是围绕其中心进行手势。
我已经安装了手势识别器,并且已经能够围绕孩子的中心进行缩放/平移/旋转。 我认为主要问题是将枢轴点(在我的情况下是用户的第一和第二指针之间的中点)转换为孩子当前的旋转角度。 第一次设置枢轴时,效果很好,但是一旦旋转视图,抬起手指,然后尝试绕另一个枢轴旋转,视图就会跳转。 这是它的外观(仅旋转):
因此,当第一次旋转发生时,它会按预期工作,并绕着两个手指之间的点旋转。 但是,一旦旋转,下一个旋转将跳到新位置。 以下是相关代码:
@Override
public boolean onRotationBegin(RotationGestureDetector detector) {
float[] coordinates = screenPointsToScaledPoints(new float[]{detector.getFocusX(), detector.getFocusY()});
pivotX = coordinates[0];
pivotY = coordinates[1];
child().setPivotX(pivotX);
child().setPivotY(pivotY);
return true;
}
@Override
public boolean onRotate(RotationGestureDetector detector) {
rotation += detector.getRotationDelta();
return true;
}
private float[] screenPointsToScaledPoints(float[] a){
mRotateMatrixInverse.mapPoints(a);
return a;
}
private void applyScaleAndTranslation() {
View child = child();
child.setRotation(rotation);
mRotateMatrix.setRotate(rotation, pivotX, pivotY);
mRotateMatrix.invert(mRotateMatrixInverse);
}
有什么想法我可能会错过吗?
好的,感谢@pskink,我设法找到了答案。 关键在这里-Android ImageView缩放和翻译问题
我的主要错误是我在使用单独的矩阵进行缩放,移动和旋转,而在建议的答案中只有一个包含所有运算的矩阵,这就是我最终要做的。 这是代码中有趣的部分:
private Matrix mMatrix = new Matrix();
private Matrix mMatrixInverse = new Matrix();
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
canvas.concat(mMatrix);
super.dispatchDraw(canvas);
canvas.restore();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
doubleFingers = ev.getPointerCount() == 2;
if (!doubleFingers) {
// Map touch coordinates to our matrix to draw correctly in the canvas.
float[] mapped = screenPointsToScaledPoints(new float[]{ev.getX(0), ev.getY(0)});
ev.setLocation(mapped[0], mapped[1]);
}
return super.dispatchTouchEvent(ev);
}
private float[] screenPointsToScaledPoints(float[] a){
mMatrix.invert(mMatrixInverse);
mMatrixInverse.mapPoints(a);
return a;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = detector.getScaleFactor();
if (scale >= MIN_CANVAS_ZOOM) {
scale *= scaleFactor;
scale = Math.max(MIN_CANVAS_ZOOM, Math.min(scale, MAX_CANVAS_ZOOM));
mMatrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());
}
return true;
}
@Override
public boolean onRotate(RotationGestureDetector detector) {
rotation += detector.getRotationDelta();
mMatrix.postRotate(detector.getRotationDelta(), detector.getFocusX(), detector.getFocusY());
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
scaleDetector.onTouchEvent(event);
rotationDetector.onTouchEvent(event);
// Lots of business logic
dX = coordinates[0] - mLastTouchX;
dY = coordinates[1] - mLastTouchY;
mLastTouchX = coordinates[0];
mLastTouchY = coordinates[1];
mMatrix.postTranslate(dX, dY);
invalidate();
return false;
}
在我的情况下,我必须手动检测两指平移,因为一个手指事件用于在OpenGL表面上绘制,因此需要从真实世界转换为缩放的矩阵坐标。 结果如下:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.