2

How can we drag more than one image in a canvas? I have a code to drag single image. I tried for moving multiple image. But it didn't work. Is there any way to do this one? This is the code for moving one image.

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;

public class MyImageView extends View {

private static final int INVALID_POINTER_ID = -1;

private Drawable mImage;
private float mPosX;
private float mPosY;

private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;

private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;

public MyImageView(Context context) {
    this(context, null, 0);
mImage = getResources().getDrawable(R.drawable.baby1);

    mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight());
   
}

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

public MyImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    
}

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

    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        final float x = ev.getX();
        final float y = ev.getY();

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

    case MotionEvent.ACTION_MOVE: {
        final int pointerIndex = ev.findPointerIndex(mActivePointerId);
        final float x = ev.getX(pointerIndex);
        final float y = ev.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;

        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 = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        final int pointerId = ev.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 = ev.getX(newPointerIndex);
            mLastTouchY = ev.getY(newPointerIndex);
            mActivePointerId = ev.getPointerId(newPointerIndex);
        }
        break;
    }
    }

    return true;
}

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();
    Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY);
    canvas.translate(mPosX, mPosY);
    canvas.scale(mScaleFactor, mScaleFactor);
    mImage.draw(canvas);
    canvas.restore();
}

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, 10.0f));

        invalidate();
        return true;
    }
}

} 
TylerH
  • 20,799
  • 66
  • 75
  • 101
Zacharias Manuel
  • 8,983
  • 1
  • 17
  • 30

2 Answers2

0

Maybe store the X Y coordinates for the multiple views you want to drag and override the onTouch and check if the xy coordinates are inside any of the imageviews (this code can be found on geeksforgeeks website in java,cpp etc),if not then don't do anything else update the coordinates of the view to 'drag' the view to the new coordinates using the code from the single choice view.the only extra step is to check using xy coordinates of the imageviews if the touch event is 'inside' the view

or check Android drag two images on canvas where it gives a library that handles all of it

TylerH
  • 20,799
  • 66
  • 75
  • 101
Aarav Shah
  • 55
  • 1
  • 7
-1

To use this snippet just add in your layout xml file:

<com.m039.study.widgets.MultiTouch
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    />

This snippet just draw circle on each finger on the view:

package com.m039.study.widgets;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.MotionEvent;
import android.view.GestureDetector;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Color;
import java.util.Stack;

public class MultiTouch extends View {

    private static final String TAG = "m039";

    public MultiTouch(Context c) {
        super(c);
    }

    public MultiTouch(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    static class Point {
        public float x;
        public float y;
        public int   pid = -1;
        public boolean isOk = false;
    }

    Paint mPaintCircle  = new Paint();
    Paint mPaintText    = new Paint();

    Stack<Point> mPoints        = new Stack<Point>();

    {

        mPaintCircle.setColor(Color.GREEN);
        mPaintText.setColor(Color.RED);
    }

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

        for (Point point : mPoints) {
            if (point.isOk) {
                canvas.drawCircle(point.x, point.y, 50, mPaintCircle);
                canvas.drawText(Integer.toString(point.pid), point.x, point.y + 50, mPaintText);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action  = event.getActionMasked();
        int pid     = (event.getAction() & event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT;
        int index   = (event.getAction() & event.ACTION_POINTER_INDEX_MASK) >> event.ACTION_POINTER_INDEX_SHIFT;

        switch (action) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:
            Point point = new Point();
            point.isOk = true;
            point.pid = pid;
            point.x = event.getX(index);
            point.y = event.getY(index);

            mPoints.push(point);

            invalidate();

            break;

        case MotionEvent.ACTION_MOVE:
            for (Point p: mPoints) {
                int pindex = event.findPointerIndex(p.pid);

                if (pindex != -1) {
                    p.x = event.getX(pindex);
                    p.y = event.getY(pindex);
                }
            }

            invalidate();
            break;

        case MotionEvent.ACTION_POINTER_UP:
            if (mPoints.size() >= 1) {
                    mPoints.pop();
            }

            invalidate();
            break;

        case MotionEvent.ACTION_UP:
        default:
            mPoints.clear();
            invalidate();

            break;
        }

        return true;
    }
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
m039
  • 1,329
  • 13
  • 11