Question

I created two bitmap on my view using the following class (Simple 2D Graphics in android) and wandering to achieve that bitmap can move independently. I am calling motionevent method for this.

Current issue, i do not understand why does only one object is moving right in the following code. e.g. with this code, only "not" bitmap is moved, i would like to move both bitmaps independently of eachother.

scenrio: i can use my two fingures, one for each object, to move the bitmaps independently. but i don't know how to achieve this.

public class TouchView extends View {

private Drawable cross;
private Rect crossBounds = null;
private Drawable not;
private Rect notBounds = null;

private int x1, y1, x2, y2 ;

boolean flag = true;

private void intialize ()
{ 
    int w1 = cross.getIntrinsicWidth();
    int h1 = cross.getIntrinsicHeight();
     x1 = 100;
    y1 = 100;
    crossBounds = new Rect(x1-w1/2, y1-w1/2, x1+w1/2, y1+h1/2);

    int w = not.getIntrinsicWidth();
    int h = not.getIntrinsicHeight();
     x2 = 300;
    y2 = 300;
    notBounds = new Rect(x2-w/2, y2-w/2, x2+w/2, y2+h/2);

}

public TouchView(Context context) {
    super(context);

    // Get a representation of the image
    Resources resources = context.getResources();
    cross = (Drawable) resources.getDrawable(R.drawable.cross);
    not = (Drawable) resources.getDrawable(R.drawable.not);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.i("TouchView.onTouchEvent", "event = " + event);

    if(event.getAction() == MotionEvent.ACTION_DOWN || 
            event.getAction() == MotionEvent.ACTION_MOVE) {

        int touchCounter = event.getPointerCount();


         if (touchCounter ==2 && getHeight ()==y1){
                int w = cross.getIntrinsicWidth();
                int h = cross.getIntrinsicHeight();
                 x1 = (int) event.getX();

                crossBounds = new Rect(x1-w/2, y1-w/2, x1+w/2, y1+h/2);
                }
                else
                {
                int w1 = not.getIntrinsicWidth();
                int h1 = not.getIntrinsicHeight();
                 x2 = (int) event.getX();

                notBounds = new Rect(x2-w1/2, y2-w1/2, x2+w1/2, y2+h1/2);
                }
                // Request the system to redraw the view (call onDraw at 
                // some point in the future)
                // From a non-UI thread, call postInvalidate instead





        invalidate();

        return true;
    }

    return false;
}



@Override
protected void onDraw(Canvas canvas) {

    Log.i("TouchView.onDraw", "");

    // Background
    Paint bgPaint = new Paint();
    bgPaint.setColor(Color.WHITE);
    canvas.drawPaint(bgPaint);

    if (flag == true){
        intialize ();
        cross.setBounds(crossBounds);
        cross.draw(canvas);
        not.setBounds(notBounds);
        not.draw(canvas);
        flag=false;
    }
    if(crossBounds != null) {
        cross.setBounds(crossBounds);
        cross.draw(canvas);
        not.setBounds(notBounds);
        not.draw(canvas);
    }
}
}
Was it helpful?

Solution

public class SimpleDrag extends View {



private final int INVALID_INDEX = -1;

private final int mTotalItems = 5;

private ArrayList<Rect> mItemsCollection;

private ArrayList<Point> mActiveDragPoints;

private ArrayList<Rect>  mActiveRects;


private Paint mPaint;

/**
 * @param context  
 * @return of type SimpleDrag
 * Constructor function
 * @since Feb 19, 2013 
 * @author rajeshcp
 */
public SimpleDrag(Context context) {
    super(context);
    init();
}

/**
 * @param context
 * @param attrs  
 * @return of type SimpleDrag
 * Constructor function
 * @since Feb 19, 2013 
 * @author rajeshcp
 */
public SimpleDrag(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

/**
 * @param context
 * @param attrs
 * @param defStyle  
 * @return of type SimpleDrag
 * Constructor function
 * @since Feb 19, 2013 
 * @author rajeshcp
 */
public SimpleDrag(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

/* (non-Javadoc)
 * @see android.view.View#onDraw(android.graphics.Canvas)
 * @since Feb 19, 2013
 * @author rajeshcp 
 */
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLUE, PorterDuff.Mode.CLEAR);
    for( Rect rect : mItemsCollection)
    {
        canvas.drawRect(rect, mPaint);
    }
}


/**
 * @param of type null
 * @return of type null
 * function which will initialize the view
 * @since Feb 20, 2013
 * @author rajeshcp
 */
private void init()
{
    mActiveRects      = new ArrayList<Rect>(mTotalItems);
    mActiveDragPoints = new ArrayList<Point>(mTotalItems);
    mItemsCollection  = new ArrayList<Rect>();
    for( int i = 0; i < mTotalItems; i++)
    {
        Rect rect = new Rect(i * 100, i * 100, (i + 1) * 100, (i + 1) * 100);
        mItemsCollection.add(rect);
    }
    mPaint     = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG | Paint.ANTI_ALIAS_FLAG);
    mPaint.setColor(Color.RED);
}





/* (non-Javadoc)
 * @see android.view.View#onTouchEvent(android.view.MotionEvent)
 * @since Feb 19, 2013
 * @author rajeshcp 
 */
@Override
public boolean onTouchEvent(MotionEvent event) {

    final int action  = event.getActionMasked();
    final int pointer = event.getActionIndex();

    switch (action) {
    case MotionEvent.ACTION_DOWN :
        Point touchDown = new Point((int)event.getX(), (int)event.getY());
        lookForIntersection(touchDown);
        break;
    case MotionEvent.ACTION_UP :
    case MotionEvent.ACTION_CANCEL :
        mActiveDragPoints.removeAll(mActiveDragPoints);
        mActiveRects.removeAll(mActiveRects);
        break;
    case MotionEvent.ACTION_MOVE :
        int count = 0;
        for(Rect rect : mActiveRects)
        {
            Point curretPoint = new Point((int)event.getX(count), (int)event.getY(count));
            moveRect(curretPoint, mActiveDragPoints.get(count), rect);
            count++;
        }
        Log.d(getClass().getName(), "Active Rects" + mActiveRects.size());
        Log.d(getClass().getName(), "Active Points" + mActiveDragPoints.size());
        invalidate();
        break;
    case MotionEvent.ACTION_POINTER_DOWN :
        touchDown = new Point((int)event.getX(pointer), (int)event.getY(pointer));
        lookForIntersection(touchDown);
        //Log.d(getClass().getName(), "ACTION_POINTER_DOWN" + pointer);
        break;
    case MotionEvent.ACTION_POINTER_UP :
        int index = getIntersectionRectIndex(new Point((int)event.getX(pointer), (int)event.getY(pointer)));
        if( index != INVALID_INDEX )
        {
            Rect rect = mItemsCollection.get(index);
            mActiveDragPoints.remove(mActiveRects.indexOf(rect));
            mActiveRects.remove(rect);
        }

        break;

    default:
        break;
    }
    return true;
}


/**
 * @param touchDown of type Point
 * @return of type null
 * function which will find the 
 * intersecting rect and add to the 
 * active collection
 * @since Feb 20, 2013
 * @author rajeshcp
 */
private void lookForIntersection(Point touchDown)
{
    final int index = getIntersectionRectIndex(touchDown);

    if( index != INVALID_INDEX )
    {
        final Rect rect = mItemsCollection.get(index);
        if( mActiveRects.indexOf(rect) == INVALID_INDEX )
        {
            mActiveDragPoints.add(touchDown);
            mActiveRects.add(mItemsCollection.get(index));
        }
    }
    Log.d(getClass().getName(), "Active Rects" + mActiveRects.size());
    Log.d(getClass().getName(), "Active Points" + mActiveDragPoints.size());

}




/**
 * @param point of type Point
 * @return of type int 
 * function which will return the index of 
 * the rect contaning the given point
 * @since Feb 20, 2013
 * @author rajeshcp
 */
private int getIntersectionRectIndex(final Point point)
{
    int index = INVALID_INDEX;
    for(Rect rect : mItemsCollection)
    {
        if( rect.contains(point.x, point.y) )
        {
            index = mItemsCollection.indexOf(rect);
            break;
        }
    }
    return index;
}


/**
 * @param currentPoint of type Point
 * @param prevPoint of type Point 
 * @param rect of type Rect
 * @return of type null
 * function which will move the change the 
 * bounds of teh rect
 * @since Feb 20, 2013
 * @author rajeshcp
 */
private void moveRect(Point currentPoint, Point prevPoint, final Rect rect)
{
    int xMoved = currentPoint.x - prevPoint.x;
    int yMoved = currentPoint.y - prevPoint.y;
    rect.set(rect.left + xMoved, rect.top + yMoved, rect.right + xMoved, rect.bottom + yMoved);
    mActiveDragPoints.set(mActiveDragPoints.indexOf(prevPoint), currentPoint);
}

}

Hope this is what you want, haven't tested a lot, but basically this is working for me even you can increase the nof items by changing the mTotalItems. Hope this will help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top