我使用canvas.drawPath绘制一个复杂的形状。这些drawPath方法的结果类似于比屏幕大的地图。我希望用户执行以下操作:使用一根手指移动地图。或者用两根手指围绕屏幕中心旋转。基本上它应该只与谷歌地图完全一样,没有缩放。到目前为止,我能够获得所需的移动和旋转:
private void handleTouch(MotionEvent event)
{
switch(event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
{
rotate=true;
move=false;
a=Math.toDegrees(-Math.atan2(event.getX(0)-event.getX(1),event.getY(0)-event.getY(1)));
if(a>360)a=a-360;
if(a<-360)a=a+360;
da=a-angle;
if(da>360)da=da-360;
if(da<-360)da=da+360;
}
break;
case MotionEvent.ACTION_POINTER_UP:
{
rotate=false;
move=false;
x = (int)event.getX();
y = (int)event.getY();
dx = x - translate.x;
dy = y - translate.y;
}
break;
case MotionEvent.ACTION_DOWN:
{
move=true;
x = (int)event.getX();
y = (int)event.getY();
dx = x - translate.x;
dy = y - translate.y;
}
break;
case MotionEvent.ACTION_MOVE:
{
if(rotate && event.getPointerCount()==2)
{
angle=Math.toDegrees((-Math.atan2(event.getX(0)-event.getX(1),event.getY(0)-event.getY(1))))-da;
if(angle>360)angle=angle-360;
if(angle<-360)angle=angle+360;
vmap.invalidate();
}
else if(move==true)
{
translate.set((int)event.getX() - dx,(int)event.getY() - dy);
//trans.setTranslate(translate.x,translate.y);
vmap.invalidate();
}
}
break;
case MotionEvent.ACTION_UP:
{
//your stuff
}
break;
}
问题是将它们正确地应用在一起。如果我先翻译然后围绕地图的中心坐标旋转,我可以轻松地围绕自己的中心旋转。但是,如果我尝试围绕屏幕中心旋转,事情就会变得复杂起来。假设我将画布向左移动了20个像素,然后将其旋转了30度,然后向下移动了50个像素,然后将其旋转了50度。如果我尝试在第二次旋转期间将两个角度加在一起,我现在将围绕一个不同的坐标旋转,这意味着只要我进行新的旋转,地图就会突然跳跃。
我研究过使用矩阵,但到目前为止还没有帮助。
答案 0 :(得分:0)
看一下Matrix课程。它允许您以多种方式转换ImageView。对于这个问题,我创建了一个包含成员的测试项目:
ImageView imageView;
Matrix imageMatrix = new Matrix();
PointF screenCenter = new PointF();
然后,在onCreate()中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenCenter.x = metrics.widthPixels/2;
screenCenter.y = metrics.heightPixels/2;
imageView = (ImageView) findViewById(R.id.image);
imageView.setScaleType(ImageView.ScaleType.MATRIX);
imageMatrix.set(imageView.getImageMatrix());
}
screenCenter对象现在包含屏幕中心的坐标,稍后将使用。 imageView比例类型已设置为MATRIX,并且imageMatrix已设置为我们更改比例类型时应用于视图的起始矩阵。
现在,当您翻译时修改imageMatrix,然后使用setImageMatrix()将新矩阵应用于视图:
void translate(float x, float y) {
imageMatrix.postTranslate(x, y);
imageView.setImageMatrix(imageMatrix);
}
旋转的工作方式相同,但我们需要屏幕中心的坐标:
void rotate(float angle) {
imageMatrix.postRotate(angle, screenCenter.x, screenCenter.y);
imageView.setImageMatrix(imageMatrix);
}
这适用于我的模拟器,平移移动预期的方向,旋转始终围绕屏幕中心移动,无论它如何翻译。不可否认,这是一个测试项目,它看起来不太漂亮。
OpenGL ES包含在Android框架中,如果你走这条路线,你可能会获得更好的图形性能。如果您这样做,那么this answer可能会有帮助。