Как создать изменяемый размер прямоугольника с пользовательскими событиями касания на Android? - программирование
Подтвердить что ты не робот

Как создать изменяемый размер прямоугольника с пользовательскими событиями касания на Android?

Я хочу создать прямоугольную форму, которая будет изменяться с помощью касаний пользователя. Ниже изображение является хорошим примером того, что я хочу сделать:

Resizable Rectangle

Есть ли какой-нибудь пример? Что мне нужно для изучения, чтобы реализовать это?

Спасибо заранее,

4b9b3361

Ответ 1

Чтобы реализовать пользовательский вид, вы получаете класс из View:) Переопределите onDraw() для внешнего вида, переопределите onTouchEvent() для обработки ввода. Обратите внимание, что в Android вы не можете рисовать поверх onDraw(); если вы хотите обновить представление, вызовите invalidate().

Вы можете использовать перетаскиваемые углы как отдельные виды. Для взглядов просто используйте готовые изображения (не стесняйтесь извлекать из ImageView). Перетаскивание осуществляется как перемещение вашего представления в ответ на события касания. RelativeLayout - ваш друг для позитивного позиционирования.

Вы можете добавить домашние макеты к макету; просто перейдите к редактированию XML и введите элемент <com.mypackage.MyViewClass>.

Ответ 2

Ответ Chintan Rathod был отличным решением, но есть что-то не так, когда Он рисует прямоугольник. Я просто редактирую некоторые строки кода, чтобы он работал правильно с событием touch touch. Теперь вы можете добавить это представление в свой макет, а затем нажать, чтобы нарисовать.

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.ihnel.englishpronounciation.R;

public class DrawView extends View {

    Point[] points = new Point[4];

    /**
     * point1 and point 3 are of same group and same as point 2 and point4
     */
    int groupId = -1;
    private ArrayList<ColorBall> colorballs = new ArrayList<ColorBall>();
    // array that holds the balls
    private int balID = 0;
    // variable to know what ball is being dragged
    Paint paint;
    Canvas canvas;

    public DrawView(Context context) {
        super(context);
        paint = new Paint();
        setFocusable(true); // necessary for getting the touch events
        canvas = new Canvas();
    }

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

    public DrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        setFocusable(true); // necessary for getting the touch events
        canvas = new Canvas();
    }

    // the method that draws the balls
    @Override
    protected void onDraw(Canvas canvas) {
        if(points[3]==null) //point4 null when user did not touch and move on screen.
            return;
        int left, top, right, bottom;
        left = points[0].x;
        top = points[0].y;
        right = points[0].x;
        bottom = points[0].y;
        for (int i = 1; i < points.length; i++) {
            left = left > points[i].x ? points[i].x:left;
            top = top > points[i].y ? points[i].y:top;
            right = right < points[i].x ? points[i].x:right;
            bottom = bottom < points[i].y ? points[i].y:bottom;
        }
        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeWidth(5);

        //draw stroke
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.parseColor("#AADB1255"));
        paint.setStrokeWidth(2);
        canvas.drawRect(
                    left + colorballs.get(0).getWidthOfBall() / 2,
                    top + colorballs.get(0).getWidthOfBall() / 2, 
                    right + colorballs.get(2).getWidthOfBall() / 2, 
                    bottom + colorballs.get(2).getWidthOfBall() / 2, paint);
        //fill the rectangle
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.parseColor("#55DB1255"));
        paint.setStrokeWidth(0);
        canvas.drawRect(
                left + colorballs.get(0).getWidthOfBall() / 2,
                top + colorballs.get(0).getWidthOfBall() / 2, 
                right + colorballs.get(2).getWidthOfBall() / 2, 
                bottom + colorballs.get(2).getWidthOfBall() / 2, paint);

        //draw the corners
        BitmapDrawable bitmap = new BitmapDrawable();
        // draw the balls on the canvas
        paint.setColor(Color.BLUE);
        paint.setTextSize(18);
        paint.setStrokeWidth(0);
        for (int i =0; i < colorballs.size(); i ++) {
            ColorBall ball = colorballs.get(i);
            canvas.drawBitmap(ball.getBitmap(), ball.getX(), ball.getY(),
                    paint);

            canvas.drawText("" + (i+1), ball.getX(), ball.getY(), paint);
        }
    }

    // events when touching the screen
    public boolean onTouchEvent(MotionEvent event) {
        int eventaction = event.getAction();

        int X = (int) event.getX();
        int Y = (int) event.getY();

        switch (eventaction) {

        case MotionEvent.ACTION_DOWN: // touch down so check if the finger is on
                                        // a ball
            if (points[0] == null) {
                //initialize rectangle.
                points[0] = new Point();
                points[0].x = X;
                points[0].y = Y;

                points[1] = new Point();
                points[1].x = X;
                points[1].y = Y + 30;

                points[2] = new Point();
                points[2].x = X + 30;
                points[2].y = Y + 30;

                points[3] = new Point();
                points[3].x = X +30;
                points[3].y = Y;

                balID = 2;
                groupId = 1;
                 // declare each ball with the ColorBall class
                for (Point pt : points) {
                     colorballs.add(new ColorBall(getContext(), R.drawable.ic_circle, pt));
                }
            } else {
                //resize rectangle
                balID = -1;
                groupId = -1;
                for (int i = colorballs.size()-1; i>=0; i--) {
                    ColorBall ball = colorballs.get(i);
                    // check if inside the bounds of the ball (circle)
                    // get the center for the ball
                    int centerX = ball.getX() + ball.getWidthOfBall();
                    int centerY = ball.getY() + ball.getHeightOfBall();
                    paint.setColor(Color.CYAN);
                    // calculate the radius from the touch to the center of the
                    // ball
                    double radCircle = Math
                            .sqrt((double) (((centerX - X) * (centerX - X)) + (centerY - Y)
                                    * (centerY - Y)));

                    if (radCircle < ball.getWidthOfBall()) {

                        balID = ball.getID();
                        if (balID == 1 || balID == 3) {
                            groupId = 2;
                        } else {
                            groupId = 1;
                        }
                        invalidate();
                        break;
                    }
                    invalidate();
                }
            }
            break;

        case MotionEvent.ACTION_MOVE: // touch drag with the ball


            if (balID > -1) {
                // move the balls the same as the finger
                colorballs.get(balID).setX(X);
                colorballs.get(balID).setY(Y);

                paint.setColor(Color.CYAN);
                if (groupId == 1) {
                    colorballs.get(1).setX(colorballs.get(0).getX());
                    colorballs.get(1).setY(colorballs.get(2).getY());
                    colorballs.get(3).setX(colorballs.get(2).getX());
                    colorballs.get(3).setY(colorballs.get(0).getY());
                } else {
                    colorballs.get(0).setX(colorballs.get(1).getX());
                    colorballs.get(0).setY(colorballs.get(3).getY());
                    colorballs.get(2).setX(colorballs.get(3).getX());
                    colorballs.get(2).setY(colorballs.get(1).getY());
                }

                invalidate();
            }

            break;

        case MotionEvent.ACTION_UP:
            // touch drop - just do things here after dropping

            break;
        }
        // redraw the canvas
        invalidate();
        return true;

    }


    public static class ColorBall {

        Bitmap bitmap;
        Context mContext;
        Point point;
        int id;
        static int count = 0;

        public ColorBall(Context context, int resourceId, Point point) {
            this.id = count++;
            bitmap = BitmapFactory.decodeResource(context.getResources(),
                    resourceId);
            mContext = context;
            this.point = point;
        }

        public int getWidthOfBall() {
            return bitmap.getWidth();
        }

        public int getHeightOfBall() {
            return bitmap.getHeight();
        }

        public Bitmap getBitmap() {
            return bitmap;
        }

        public int getX() {
            return point.x;
        }

        public int getY() {
            return point.y;
        }

        public int getID() {
            return id;
        }

        public void setX(int x) {
            point.x = x;
        }

        public void setY(int y) {
            point.y = y;
        }
    }
}

Ответ 3

Следующий код - рисовать прямоугольник на сенсорной базе.

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.common.Utils;
import com.example.rectangleoverlay.R;

public class DrawView extends View {

    Point point1, point3;
    Point point2, point4;

    /**
     * point1 and point 3 are of same group and same as point 2 and point4
     */
    int groupId = -1;
    private ArrayList<ColorBall> colorballs = new ArrayList<ColorBall>();
    // array that holds the balls
    private int balID = 0;
    // variable to know what ball is being dragged
    Paint paint;
    Canvas canvas;

    public DrawView(Context context) {
        super(context);
        paint = new Paint();
        setFocusable(true); // necessary for getting the touch events
        canvas = new Canvas();
        // setting the start point for the balls
        point1 = new Point();
        point1.x = 50;
        point1.y = 20;

        point2 = new Point();
        point2.x = 150;
        point2.y = 20;

        point3 = new Point();
        point3.x = 150;
        point3.y = 120;

        point4 = new Point();
        point4.x = 50;
        point4.y = 120;

        // declare each ball with the ColorBall class
        colorballs.add(new ColorBall(context, R.drawable.gray_circle, point1));
        colorballs.add(new ColorBall(context, R.drawable.gray_circle, point2));
        colorballs.add(new ColorBall(context, R.drawable.gray_circle, point3));
        colorballs.add(new ColorBall(context, R.drawable.gray_circle, point4));

    }

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

    public DrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        setFocusable(true); // necessary for getting the touch events
        canvas = new Canvas();
        // setting the start point for the balls
        point1 = new Point();
        point1.x = 50;
        point1.y = 20;

        point2 = new Point();
        point2.x = 150;
        point2.y = 20;

        point3 = new Point();
        point3.x = 150;
        point3.y = 120;

        point4 = new Point();
        point4.x = 50;
        point4.y = 120;

        // declare each ball with the ColorBall class
        colorballs.add(new ColorBall(context, R.drawable.gray_circle, point1));
        colorballs.add(new ColorBall(context, R.drawable.gray_circle, point2));
        colorballs.add(new ColorBall(context, R.drawable.gray_circle, point3));
        colorballs.add(new ColorBall(context, R.drawable.gray_circle, point4));

    }

    // the method that draws the balls
    @Override
    protected void onDraw(Canvas canvas) {
        // canvas.drawColor(0xFFCCCCCC); //if you want another background color

        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setColor(Color.parseColor("#55000000"));
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeJoin(Paint.Join.ROUND);
        // mPaint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth(5);

        canvas.drawPaint(paint);
        paint.setColor(Color.parseColor("#55FFFFFF"));

        if (groupId == 1) {
            canvas.drawRect(point1.x + colorballs.get(0).getWidthOfBall() / 2,
                    point3.y + colorballs.get(2).getWidthOfBall() / 2, point3.x
                            + colorballs.get(2).getWidthOfBall() / 2, point1.y
                            + colorballs.get(0).getWidthOfBall() / 2, paint);
        } else {
            canvas.drawRect(point2.x + colorballs.get(1).getWidthOfBall() / 2,
                    point4.y + colorballs.get(3).getWidthOfBall() / 2, point4.x
                            + colorballs.get(3).getWidthOfBall() / 2, point2.y
                            + colorballs.get(1).getWidthOfBall() / 2, paint);
        }
        BitmapDrawable mBitmap;
        mBitmap = new BitmapDrawable();

        // draw the balls on the canvas
        for (ColorBall ball : colorballs) {
            canvas.drawBitmap(ball.getBitmap(), ball.getX(), ball.getY(),
                    new Paint());
        }
    }

    // events when touching the screen
    public boolean onTouchEvent(MotionEvent event) {
        int eventaction = event.getAction();

        int X = (int) event.getX();
        int Y = (int) event.getY();

        switch (eventaction) {

        case MotionEvent.ACTION_DOWN: // touch down so check if the finger is on
                                        // a ball
            balID = -1;
            groupId = -1;
            for (ColorBall ball : colorballs) {
                // check if inside the bounds of the ball (circle)
                // get the center for the ball
                Utils.logd("Id : " + ball.getID());
                Utils.logd("getX : " + ball.getX() + " getY() : " + ball.getY());
                int centerX = ball.getX() + ball.getWidthOfBall();
                int centerY = ball.getY() + ball.getHeightOfBall();
                paint.setColor(Color.CYAN);
                // calculate the radius from the touch to the center of the ball
                double radCircle = Math
                        .sqrt((double) (((centerX - X) * (centerX - X)) + (centerY - Y)
                                * (centerY - Y)));

                Utils.logd("X : " + X + " Y : " + Y + " centerX : " + centerX
                        + " CenterY : " + centerY + " radCircle : " + radCircle);

                if (radCircle < ball.getWidthOfBall()) {

                    balID = ball.getID();
                    Utils.logd("Selected ball : " + balID);
                    if (balID == 1 || balID == 3) {
                        groupId = 2;
                        canvas.drawRect(point1.x, point3.y, point3.x, point1.y,
                                paint);
                    } else {
                        groupId = 1;
                        canvas.drawRect(point2.x, point4.y, point4.x, point2.y,
                                paint);
                    }
                    invalidate();
                    break;
                }
                invalidate();
            }

            break;

        case MotionEvent.ACTION_MOVE: // touch drag with the ball
            // move the balls the same as the finger
            if (balID > -1) {
                Utils.logd("Moving Ball : " + balID);

                colorballs.get(balID).setX(X);
                colorballs.get(balID).setY(Y);

                paint.setColor(Color.CYAN);

                if (groupId == 1) {
                    colorballs.get(1).setX(colorballs.get(0).getX());
                    colorballs.get(1).setY(colorballs.get(2).getY());
                    colorballs.get(3).setX(colorballs.get(2).getX());
                    colorballs.get(3).setY(colorballs.get(0).getY());
                    canvas.drawRect(point1.x, point3.y, point3.x, point1.y,
                            paint);
                } else {
                    colorballs.get(0).setX(colorballs.get(1).getX());
                    colorballs.get(0).setY(colorballs.get(3).getY());
                    colorballs.get(2).setX(colorballs.get(3).getX());
                    colorballs.get(2).setY(colorballs.get(1).getY());
                    canvas.drawRect(point2.x, point4.y, point4.x, point2.y,
                            paint);
                }

                invalidate();
            }

            break;

        case MotionEvent.ACTION_UP:
            // touch drop - just do things here after dropping

            break;
        }
        // redraw the canvas
        invalidate();
        return true;

    }

    public void shade_region_between_points() {
        canvas.drawRect(point1.x, point3.y, point3.x, point1.y, paint);
    }
}

Следующий класс используется для хранения объектов

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;

public class ColorBall {

    Bitmap bitmap;
    Context mContext;
    Point point;
    int id;
    static int count = 0;

    public ColorBall(Context context, int resourceId, Point point) {
        this.id = count++;
        bitmap = BitmapFactory.decodeResource(context.getResources(),
                resourceId);
        mContext = context;
        this.point = point;
    }

    public int getWidthOfBall() {
        return bitmap.getWidth();
    }

    public int getHeightOfBall() {
        return bitmap.getHeight();
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public int getX() {
        return point.x;
    }

    public int getY() {
        return point.y;
    }

    public int getID() {
        return id;
    }

    public void setX(int x) {
        point.x = x;
    }

    public void setY(int y) {
        point.y = y;
    }
}

Ответ 4

Следующий код - это версия С# (в настоящее время я разрабатываю приложение на MonoDroid/Xamarin) запрошенного кода, но с некоторыми улучшениями и возможностью перетаскивания прямоугольника. Все еще хотите добавить некоторые функции, отредактируйте их позже.

namespace ImagePlayground
{
[Activity (Label = "MyView2")]          
public class MyView2 : View
{
    Graphics.Point[] points = new Graphics.Point[4];

    // Array that hold the circle
    private List<ResizeCircle> circles = new List<ResizeCircle>();

    // Variable to keep tracking of which circle is being dragged
    private int circleId = -1;

    // Points are grouped in groups of two so there always only one fixed point       
    // groupId = 0 > Touch Inside the Rectangle
    // groupId = 1 > Points 0 and 2
    // groupId = 2 > Points 1 and 3
    int groupId = -1;

    // FirstTouch Coordinate for Tracking on Dragging
    int xFirstTouch = 0;
    int yFirstTouch = 0;

    /** Main Bitmap **/
    private Bitmap mBitmap = null;

    /** Measured Size of the View **/
    private Rect mMeasuredRect;

    /** Paint to Draw Rectangles **/
    private Paint mRectPaint;

    public MyView2(Context ctx) : base (ctx){
        init (ctx);
    }

    public MyView2 (Context ctx, IAttributeSet attrs) : base (ctx, attrs){
        init (ctx);
    }

    public MyView2 (Context ctx, IAttributeSet attrs, int defStyle) : base(ctx,attrs,defStyle){
        init (ctx);
    }

    private void init(Context ctx){
        // For Touch Events
        Focusable = true;
        // Draw the Image on the Background
        mBitmap = BitmapFactory.DecodeResource(ctx.Resources, Resource.Drawable.bg);

        // Sets up the paint for the Drawable Rectangles
        mRectPaint = new Paint ();
        mRectPaint.Color = Android.Graphics.Color.Aqua;
        mRectPaint.StrokeWidth = 4;
        mRectPaint.SetStyle (Paint.Style.Stroke);
    }

    protected override void OnDraw(Canvas canvas){
        // Background Bitmap to Cover all Area
        canvas.DrawBitmap(mBitmap, null, mMeasuredRect, null);

        // Just draw the points only if it has already been initiated
        if (points [3] != null) {               
            int left, top, right, bottom;
            left = points [0].X;
            top = points [0].Y;
            right = points [0].X;
            bottom = points [0].Y;

            // Sets the circles' locations
            for (int i = 1; i < points.Length; i++) {
                left = left > points [i].X ? points [i].X : left;
                top = top > points [i].Y ? points [i].Y : top;
                right = right < points [i].X ? points [i].X : right;
                bottom = bottom < points [i].Y ? points [i].Y : bottom;
            }

            mRectPaint.AntiAlias = true;
            mRectPaint.Dither = true;
            mRectPaint.StrokeJoin = Paint.Join.Round;
            mRectPaint.StrokeWidth = 5;
            mRectPaint.SetStyle (Paint.Style.Stroke);
            mRectPaint.Color = Graphics.Color.ParseColor ("#0079A3");

            canvas.DrawRect (
                left + circles [0].GetCircleWidth () / 2,
                top + circles [0].GetCircleWidth () / 2, 
                right + circles [2].GetCircleWidth () / 2, 
                bottom + circles [2].GetCircleWidth () / 2, mRectPaint);

            // Fill The Rectangle
            mRectPaint.SetStyle (Paint.Style.Fill);
            mRectPaint.Color = Graphics.Color.ParseColor ("#B2D6E3");
            mRectPaint.Alpha = 75;
            mRectPaint.StrokeWidth = 0;

            canvas.DrawRect (
                left + circles [0].GetCircleWidth () / 2,
                top + circles [0].GetCircleWidth () / 2, 
                right + circles [2].GetCircleWidth () / 2, 
                bottom + circles [2].GetCircleWidth () / 2, mRectPaint);

            // DEBUG
            mRectPaint.Color = Graphics.Color.Red;
            mRectPaint.TextSize = 18;
            mRectPaint.StrokeWidth = 0;

            // Draw every circle on the right position
            for (int i = 0; i < circles.Count (); i++) {
                ResizeCircle circle = circles [i];
                float x = circle.GetX ();
                float y = circle.GetY ();
                canvas.DrawBitmap (circle.GetBitmap (), x, y,
                    mRectPaint);

                // DEBUG
  //                    canvas.DrawText ("" + (i + 1), circle.GetX (), circle.GetY (), mRectPaint);
            }
        }
    }

    public override bool OnTouchEvent(MotionEvent e){

        // Get the Coordinates of Touch
        int xTouch = (int) e.GetX ();
        int yTouch = (int) e.GetY ();
        int actionIndex = e.ActionIndex;

        switch (e.ActionMasked) {
        // In case user touch the screen
        case MotionEventActions.Down:

            // If no points were created
            if (points [0] == null) {
                // Offset to create the points
                int offset = 60;
                // Initialize a new Rectangle.
                points [0] = new Graphics.Point ();
                points [0].X = xTouch;
                points [0].Y = yTouch;

                points [1] = new Graphics.Point ();
                points [1].X = xTouch;
                points [1].Y = yTouch + offset;

                points [2] = new Graphics.Point ();
                points [2].X = xTouch + offset;
                points [2].Y = yTouch + offset;

                points [3] = new Graphics.Point ();
                points [3].X = xTouch + offset;
                points [3].Y = yTouch;

                // Add each circle to circles array
                foreach (Graphics.Point pt in points) {
                    circles.Add (new ResizeCircle (Context, Resource.Drawable.circle, pt));
                }
            } else {
                // Register Which Circle (if any) th user has touched
                groupId = getTouchedCircle (xTouch, yTouch);
                xFirstTouch = xTouch;
                yFirstTouch = yTouch;

            }
            break;
        case MotionEventActions.PointerDown:
            break;

        case MotionEventActions.Move:                                               
            if (groupId == 1 || groupId == 2) {

                // Move touched Circle as the finger moves
                circles[circleId].SetX(xTouch);
                circles[circleId].SetY(yTouch);

                // Move the two other circles accordingly
                if (groupId == 1) {
                    circles[1].SetX(circles[0].GetX());
                    circles[1].SetY(circles[2].GetY());
                    circles[3].SetX(circles[2].GetX());
                    circles[3].SetY(circles[0].GetY());
                } else {                        
                    circles[0].SetX(circles[1].GetX());
                    circles[0].SetY(circles[3].GetY());
                    circles[2].SetX(circles[3].GetX());
                    circles[2].SetY(circles[1].GetY());
                }
                Invalidate();
            } else if (groupId == 0){
                // Calculate the delta for the dragging
                int xDelta =  (xTouch-xFirstTouch);
                int yDelta =  (yTouch-yFirstTouch);
                xFirstTouch = xTouch;
                yFirstTouch = yTouch;

                // Move each circle accordingly
                foreach (ResizeCircle circle in circles) {
                    circle.SetX (circle.GetX () + xDelta);
                    circle.SetY (circle.GetY () + yDelta);
                }

                // Redraw the view
                Invalidate ();              
            }
            break;

        case MotionEventActions.Up:
            break;
        default:
            break;          
        }
        Invalidate ();
        return true;
    }


    private int getTouchedCircle(int xTouch, int yTouch){
        int groupId = -1;
        for (int i = 0; i < circles.Count; i++) {
            ResizeCircle circle = circles [i];

            // Check if the touch was inside the bounds of the circle
            int centerX = circle.GetX () + circle.GetCircleWidth ();
            int centerY = circle.GetY () + circle.GetCircleHeight ();

            // Calculate the radius from the touch to the center of the circle
            double radCircle = Math.Sqrt ((double)(((centerX - xTouch) * (centerX - xTouch)) + (centerY - yTouch)
                * (centerY - yTouch)));

            // If the touch was on one of the circles
            if (radCircle < circle.GetCircleWidth ()) {
                circleId = circle.GetID ();
                if (circleId == 1 || circleId == 3) {
                    groupId = 2;
                    break;
                } else {
                    groupId = 1;
                    break;
                }
            } else {
                // User didn't touch any of the circles nor the inside area
                groupId = -1;
            }
        }
        // If the touch wasn't on one of the circles, check if it was inside the rectangle
        if (groupId == -1) {
            List<int> xCoords = new List<int> ();
            List<int> yCoords = new List<int> ();

            // Gather Coordinates from all circles      
            foreach (ResizeCircle circle in circles){
                xCoords.Add (circle.GetX());
                yCoords.Add (circle.GetY());
            }

            // Store the max and min coordinates
            int minX = xCoords.Min ();
            int maxX = xCoords.Max ();
            int minY = yCoords.Min ();
            int maxY = yCoords.Max ();

            // Check if user has touched inside the rectangle
            if ((xTouch > minX && xTouch < maxX) && (yTouch > minY && yTouch < maxY)) {
                // User has touched inside the Rectangle
                groupId = 0;
            }
        }

        return groupId;
    }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec){
        base.OnMeasure (widthMeasureSpec, heightMeasureSpec);

        mMeasuredRect = new Rect (0, 0, MeasuredWidth, MeasuredHeight);
    }

    public class ResizeCircle {

        Bitmap bitmap;
        Graphics.Point point;
        int id;
        static int count = 0;

        public ResizeCircle(Context context, int resourceId, Graphics.Point point) {
            this.id = count++;
            bitmap = BitmapFactory.DecodeResource(context.Resources,
                resourceId);
            Log.Debug("BITMAP" , bitmap.Height.ToString());
            this.point = point;
        }

        public int GetCircleWidth() {
            return bitmap.Width;
        }

        public int GetCircleHeight() {
            return bitmap.Height;
        }

        public Bitmap GetBitmap() {
            return bitmap;
        }

        public int GetX() {
            return point.X;
        }

        public int GetY() {
            return point.Y;
        }

        public int GetID() {
            return id;
        }

        public void SetX(int x) {
            point.X = x;
        }

        public void SetY(int y) {
            point.Y = y;
        }
    }
   }
  }

Ответ 5

Отредактированный ответ Нгуен Минь Бинь работал у меня. Но мне нужно было добавить облегченное исправление, чтобы не допустить, чтобы идентификатор мяча вышел из диапазона. Это произошло для меня, если мне пришлось повторно открыть активность, на которой размещается пользовательский вид. Я исправил эту строку:

this.id = count ++;

в

if (count > 3) count = 0; 
this.id = count++;