0

I'm new in ANDROID and want to rotate, zoom and move an image in my own custom view. But I write all of them(rotate, zoom, move) in same onTouchEvent method. So when I move image, it is also rotated or I zoom image,it is moved. I have to handle them separately but don't know how. I think i can add a button,for example which name is "rotate". So I can fix image and it just allow to rotate. But i can't create button in my custom view. The code is shown below:

public class MyView extends View {

// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
private static final int INVALID_POINTER_ID = -1;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;

private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;

//For Fetching image
private Bitmap bmp;
private Drawable image;
private byte[] byteArray;
private ByteArrayBuffer baf = null;

//For Rotation
int direction = 0;
int degree = 0;
private float centerX ;
private float centerY ;
private float newX ;
private float newY ;
private float rotateX;
private float rotateY;

public MyView(Context context) {
    this(context, null, 0);
}

public MyView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    String url = "http://www.queness.com/resources/images/png/apple_ex.png";    

    AsyncTask<String,Void,ByteArrayBuffer> connection=new GetUrlData().execute(url);

    try {
        baf=connection.get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }

    byteArray =  baf.toByteArray();
    bmp = BitmapFactory.decodeByteArray(byteArray, 0 , byteArray.length);

    image =new BitmapDrawable(context.getResources() , bmp);
    image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());    
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLACK);


    //For Rotation
    int height = this.getHeight();
    int width = this.getWidth();
    centerX = width/2;
    centerY = height/2;
    canvas.rotate(direction, width / 2, height / 2);

    canvas.save();
    canvas.translate(mPosX, mPosY);
    canvas.scale(mScaleFactor, mScaleFactor);
    image.draw(canvas);
    canvas.restore();   
}

//For Rotation
private void updateRotation(float newX2, float newY2) {

    degree = (int)Math.toDegrees(Math.atan2(newY, newX))-90;

    setDirection(degree);
}
//For Rotation
public void setDirection(int direction) {
    this.direction = direction;
    this.invalidate();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // Let the ScaleGestureDetector inspect all events.
    mScaleDetector.onTouchEvent(event);

    final int action = event.getAction();

    if (action == MotionEvent.ACTION_DOWN) {
        final float x = event.getX();
        final float y = event.getY();

        mLastTouchX = x;
        mLastTouchY = y;
        mActivePointerId = event.getPointerId(0); 
    }

    if (action == MotionEvent.ACTION_MOVE) {
        final int pointerIndex = event.findPointerIndex(mActivePointerId);
        final float x = event.getX(pointerIndex);
        final float y = event.getY(pointerIndex);

        // Only move if the ScaleGestureDetector isn't processing a gesture.
        if (!mScaleDetector.isInProgress()) {
            final float dx = x - mLastTouchX;
            final float dy = y - mLastTouchY;

            mPosX += dx;
            mPosY += dy;

            invalidate();
        }

        mLastTouchX = x;
        mLastTouchY = y;

        //For Rotation
        rotateX =   event.getX();
        rotateY =   event.getY();

        newX =  centerX-rotateX;
        newY = centerY-rotateY;

        updateRotation( newX,  newY);

    }

    if (action == MotionEvent.ACTION_UP) {
        mActivePointerId = INVALID_POINTER_ID;

        updateRotation( newX,  newY);
    }

    if (action == MotionEvent.ACTION_CANCEL) {
        mActivePointerId = INVALID_POINTER_ID;
    }

    if (action == MotionEvent.ACTION_POINTER_UP) {
        final int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        final int pointerId = event.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 = event.getX(newPointerIndex);
            mLastTouchY = event.getY(newPointerIndex);
            mActivePointerId = event.getPointerId(newPointerIndex);
        }

    }

    return true;
}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        mScaleFactor *= detector.getScaleFactor();

        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));

        invalidate();
        return true;
    }
}

}

I hope i can tell what i want. Could you help me about this question please?

angaraeski
  • 468
  • 1
  • 6
  • 12
  • 2
    understand all the concepts and write all the codes in together and i suggest you to understand and dont make copy paste – Thiru VT May 23 '12 at 12:57
  • look at this http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html – Padma Kumar May 23 '12 at 13:21
  • @ThiruVT You're completely right about your comment. I copied-pasted my code and realize that I wasn't aware anything about my question.But after then, i searched and understood what's all about and handled my problem on my own. So thanks your advice. – angaraeski May 28 '12 at 13:49
  • @PadmaKumar thanks to you too for sharing. – angaraeski May 28 '12 at 13:51

1 Answers1

2

Try with below code its working for me.

float[] lastEvent = null;
float d = 0f;
float newRot = 0f;
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
public static String fileNAME;
public static int framePos = 0;

private float scale = 0;
private float newDist = 0;

// Fields
private String TAG = this.getClass().getSimpleName();

// We can be in one of these 3 states
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;

// Remember some things for zooming
private PointF start = new PointF();
private PointF mid = new PointF();
float oldDist = 1f;

 public boolean onTouch(View v, MotionEvent event) {
            ImageView view = (ImageView) v;

            // Handle touch events here...
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix);
                start.set(event.getX(), event.getY());
                mode = DRAG;
                lastEvent = null;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    mode = ZOOM;
                }
                lastEvent = new float[4];
                lastEvent[0] = event.getX(0);
                lastEvent[1] = event.getX(1);
                lastEvent[2] = event.getY(0);
                lastEvent[3] = event.getY(1);
                d = rotation(event);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                lastEvent = null;
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {
                    // ...
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - start.x, event.getY()
                            - start.y);
                } else if (mode == ZOOM && event.getPointerCount() == 2) {
                    float newDist = spacing(event);
                    matrix.set(savedMatrix);
                    if (newDist > 10f) {
                        float scale = newDist / oldDist;
                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
                    if (lastEvent != null) {
                        newRot = rotation(event);
                        float r = newRot - d;
                        matrix.postRotate(r, view.getMeasuredWidth() / 2,
                                view.getMeasuredHeight() / 2);
                    }
                }
                break;
            }

            view.setImageMatrix(matrix);

            return true;
        }

//For rotate image on multi-touch.

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);
}
private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }
kyogs
  • 6,766
  • 1
  • 34
  • 50