1

I have multiple ImageViews dynamically added to an activity and I want all the ImageViews to be rotated and scaled on touch gestures (on them) . I had been searching a lot, all I could is

1) Below class for handling rotation gesture and to find angle of rotation needed

public class RotationGestureDetector {
    private static final int INVALID_POINTER_ID = -1;
    private float fX, fY, sX, sY;
    private int ptrID1, ptrID2;
    private float mAngle;

    private OnRotationGestureListener mListener;

    public float getAngle() {
        return mAngle;
    }

    public RotationGestureDetector(OnRotationGestureListener listener){
        mListener = listener;
        ptrID1 = INVALID_POINTER_ID;
        ptrID2 = INVALID_POINTER_ID;
    }

    public boolean onTouchEvent(MotionEvent event,ImageView newImageView){
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                ptrID1 = event.getPointerId(event.getActionIndex());
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                ptrID2 = event.getPointerId(event.getActionIndex());
                sX = event.getX(event.findPointerIndex(ptrID1));
                sY = event.getY(event.findPointerIndex(ptrID1));
                fX = event.getX(event.findPointerIndex(ptrID2));
                fY = event.getY(event.findPointerIndex(ptrID2));
                break;
            case MotionEvent.ACTION_MOVE:
                if(ptrID1 != INVALID_POINTER_ID && ptrID2 != INVALID_POINTER_ID){
                    float nfX, nfY, nsX, nsY;
                    nsX = event.getX(event.findPointerIndex(ptrID1));
                    nsY = event.getY(event.findPointerIndex(ptrID1));
                    nfX = event.getX(event.findPointerIndex(ptrID2));
                    nfY = event.getY(event.findPointerIndex(ptrID2));

                    mAngle = angleBetweenLines(fX, fY, sX, sY, nfX, nfY, nsX, nsY);

                    if (mListener != null) {
                        mListener.OnRotation(this, newImageView);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                ptrID1 = INVALID_POINTER_ID;
                break;
            case MotionEvent.ACTION_POINTER_UP:
                ptrID2 = INVALID_POINTER_ID;
                break;
        }
        return true;
    }

    private float angleBetweenLines (float fX, float fY, float sX, float sY, float nfX, float nfY, float nsX, float nsY)
    {
        float angle1 = (float) Math.atan2( (fY - sY), (fX - sX) );
        float angle2 = (float) Math.atan2( (nfY - nsY), (nfX - nsX) );

        float angle = ((float)Math.toDegrees(angle1 - angle2)) % 360;
        if (angle < -180.f) angle += 360.0f;
        if (angle > 180.f) angle -= 360.0f;
        return angle;
    }

    public static interface OnRotationGestureListener {
        public void OnRotation(RotationGestureDetector rotationDetector,ImageView newImageView);
    }
}

2) Below code for rotating my ImageView with the obtained angle, it works but crashes and response is very slow.

Matrix mat = new Matrix();
Bitmap bMap = ((BitmapDrawable)newImageView.getDrawable()).getBitmap(); ;
mat.postRotate(angle, bMap.getWidth()/2,bMap.getHeight()/2);
Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0,bMap.getWidth(),bMap.getHeight(), mat, true);
newImageView.setImageBitmap(bMapRotate);

3) I tried AnimationRotation, but in that case Image is being rotated not the ImageView.

Also in both of the above cases the ImageView is shown in old postion on touching it.

I'm using the below code for handling "Drag".

@Override
            public boolean onTouch(View v, MotionEvent event) 
            {
                 mRotationDetector.onTouchEvent(event, newImageView);

                float x = event.getX();
                 float y = event.getY();


                System.out.println("matrix=" + savedMatrix.toString());



                switch(event.getAction())
                {
                    case MotionEvent.ACTION_DOWN :
                    {

                        parms = (RelativeLayout.LayoutParams) newImageView.getLayoutParams();


                        dx = event.getRawX() - parms.leftMargin;
                        dy = event.getRawY() - parms.topMargin;
                        touchFlag=1;






                    }
                    break;
                    case MotionEvent.ACTION_MOVE :
                    {
                        touchFlag=0;
                        x = event.getRawX();
                        y = event.getRawY();
                        parms.leftMargin = (int) (x-dx);
                        parms.topMargin = (int) (y - dy);
                        newImageView.setLayoutParams(parms);





                    }
                    break;
                case MotionEvent.ACTION_UP :
                    {



                    }
                    break;
                }


                return false;
            }



        });

Please give me some useful link or code , thanks in advance

  • see my answer here http://stackoverflow.com/questions/21633545/android-imageview-scaling-and-translating-issue – pskink Jul 01 '14 at 11:01
  • of course if you don't want to move/translate the image you can remove SimpleOnMoveGestureListener from my code – pskink Jul 01 '14 at 11:55
  • but if you need move/translate you could add some checks for the image not to leave the screen bounds – pskink Jul 01 '14 at 17:27
  • those checks are easy to implement using the mapped rectangle returned by Matrix.mapRect method – pskink Jul 02 '14 at 05:49

0 Answers0