Я пытаюсь сделать вид, следуя моему пальцу, и сделаю поворот и масштабирование в мультитач со следующим кодом
@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);
Я работаю над этой работой в течение последних двух дней без успеха.
ПРИМЕЧАНИЕ. То, что я пытаюсь достичь, - это сделать поворот вида и масштабировать с помощью двух пальцев (перетащите также одним пальцем) Я следил за кодом перетаскивания из документации Google, чтобы он не прыгал при переключении пальцев. Я использую это для поворота view.animate(). rotationBy (a).setDuration(0).setInterpolator(новый 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;
}