我正在尝试按照我的手指进行视图,并使用以下代码在多点触控中进行一些旋转和缩放
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
final int action = motionEvent.getActionMasked();
int newPosX,newPosY;
switch (action) {
case MotionEvent.ACTION_DOWN: {
final int pointerIndex = motionEvent.getActionIndex();
final float x = motionEvent.getX( pointerIndex);
final float y = motionEvent.getY( pointerIndex);
RelativeLayout.LayoutParams parms = (RelativeLayout.LayoutParams) view.getLayoutParams();
// Remember where we started (for dragging)
mLastTouchX = (int) x;
mLastTouchY = (int) y;
// Save the ID of this pointer (for dragging)
mActivePointerId = motionEvent.getPointerId( 0);
break;
}
case MotionEvent.ACTION_MOVE: {
if(motionEvent.getPointerCount()==2){
float newDist = spacing(motionEvent);
float scale = newDist / oldDist * view.getScaleX();
view.setScaleY(scale);
view.setScaleX(scale);
float newAngle = rotation(motionEvent);
float a = newAngle - oldAngle;
view.animate().rotationBy(a).setDuration(0).setInterpolator(new LinearInterpolator()).start();
}
// Find the index of the active pointer and fetch its position
final int pointerIndex =
motionEvent.findPointerIndex( mActivePointerId);
final float x = motionEvent.getX( pointerIndex);
final float y = motionEvent.getY( pointerIndex);
// Calculate the distance moved
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin += dx;
layoutParams.topMargin += dy;
view.setLayoutParams(layoutParams);
break;
}
case MotionEvent.ACTION_POINTER_DOWN:{
oldDist = spacing(motionEvent);
oldAngle = rotation(motionEvent);
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = motionEvent.getActionIndex();
final int pointerId = motionEvent.getPointerId( pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = (int) motionEvent.getX( newPointerIndex);
mLastTouchY = (int) motionEvent.getY( newPointerIndex);
mActivePointerId = motionEvent.getPointerId( newPointerIndex);
}
break;
}
}
return true;
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
一切正常直到视图旋转。当它旋转超过90度并且我们试图拖动它时它会在触摸点周围跳跃。我认为它与
有关layoutParams.leftMargin += dx;
layoutParams.topMargin += dy;
setLayoutParams(layoutParams);
我正在努力使这项工作最近两天没有成功。
注意:我想要实现的是使视图拖动旋转并用2个手指缩放(也用单个手指拖动) 我按照Google的文档中的拖拽代码进行操作,以便在切换手指时不会跳转。 我用它来旋转 view.animate()。rotationBy(a).setDuration(0).setInterpolator(new LinearInterpolator())。start();
因为当我使用view.setRotate()时,视图正在振动。
编辑1: 我删除了
layoutParams.leftMargin += dx;
layoutParams.topMargin += dy;
并将其替换为:
//To get the moved distance of the finger(X and Y)
float diffX = motionEvent.getX(pointerIndex) - mLastTouchX;
float diffY = motionEvent.getY(pointerIndex) - mLastTouchY;
//to get the distance from touch point and the top or left of the view
final float dx = motionEvent.getRawX() - (motionEvent.getRawX()-motionEvent.getX());
final float dy = motionEvent.getRawY() - (motionEvent.getRawY()-motionEvent.getY());
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
//Settings appropriate value for the margin top and margin left.
layoutParams.leftMargin = (int) ((( motionEvent.getRawX() )-dx )+ diffX );
layoutParams.topMargin = (int) ((( motionEvent.getRawY() )-dy )+ diffY );
现在即使旋转后视图也没有四处移动。但当我切换活动手指时,它会从实际位置跳跃。
在ACTION_POINTER_UP上我这样做是为了改变活动手指的移位
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = motionEvent.getActionIndex();
final int pointerId = motionEvent.getPointerId( pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
Log.d(TAG,"New pointer index :"+newPointerIndex);
mLastTouchX = (int) motionEvent.getX( newPointerIndex);
mLastTouchY = (int) motionEvent.getY( newPointerIndex);
mActivePointerId = motionEvent.getPointerId( newPointerIndex);
}
break;
}
答案 0 :(得分:2)
通常我建议不要在运行时过度操纵视图的位置和大小,它会不必要地更新布局,降低性能,难以控制,很少看起来很好。
相反,如果您不想深入研究OpenGl,那么我的建议是自定义视图,创建一个extend View
的类,稍后您将在布局XML中添加该类, <com.packagename.MyCustomView ... />
。
此视图将具有整个屏幕的大小。
您@Override
方法onDraw(Canvas canvas)
,它会为您提供视图画布,您可以使用画布在视图中绘制图形。
在invalidate();
的末尾写onDraw()
告诉View尝试再次调用onDraw(),一旦用户停止触摸你的视图就应该停止调用它,所以添加一些布尔值到它
现在有了触摸,您可以注册触摸事件,就像在自定义视图中一样触摸事件,并使用canvas.getWidth()
和canvas.getHeight()
中的x,y和视图大小来确定要执行的操作做。
如果您在到达onDraw()覆盖onMeasure()
之前需要视图的大小。
<强>综述强>
这可能看起来不那么容易,但它很快且退出效率很高,图形会很流畅,如果你想要最好的结果并且不怕大量代码那么你可以使用OpenGl查看绘图但是我不会建议你做什么。
希望我理解这个问题并帮助你 - 祝你好运!