I am trying to make a view follow my finger and do some rotation and scaling in multitouch with the following code
@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); }
Everything is working well until the view is rotated. When it is rotated above 90 degrees and we try to drag it it's jumping around the touch point. I think it has something to do with
layoutParams.leftMargin += dx; layoutParams.topMargin += dy; setLayoutParams(layoutParams);
I am working to make this work for last two days with no success.
NOTE: what I am trying to achieve is to make a view drag rotate and scale with 2 fingers(drag with single finger also) I followed the drag code from Google's documentation so as to make it not jump while switching fingers. I am using this to rotate view.animate().rotationBy(a).setDuration(0).setInterpolator(new LinearInterpolator()).start();
because when i use view.setRotate(),the view is vibrating.
EDIT 1: I removed
layoutParams.leftMargin += dx; layoutParams.topMargin += dy;
and replaced it with:
//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 );
Now even after rotating the view is not moving around. but when i switch the active finger its jumping around from the actual position.
On ACTION_POINTER_UP i am doing this to change shift the active finger
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 comments:
Post a Comment