You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android(Java):基于后端坐标在图片上绘制可点击矩形/正方形

Android自定义View实现可点击的动态矩形绘制

我从后端获取了一组坐标,需要在Android(Java)应用中依据这些坐标在图片上绘制矩形或正方形,且绘制的图形需支持点击操作。以下是我当前实现的自定义View代码:

public class DrawView extends View {
Paint paint = new Paint();

private void init() {
    paint.setColor(Color.BLACK);
}

public DrawView(Context context) {
    super(context);
    init();
}

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

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

@Override
public void onDraw(Canvas canvas) {
    canvas.drawRoundRect(150,150,300,300,10,10,paint);
    canvas.drawRect(300, 300, 600, 600,paint);
}
}

解决方案

1. 创建矩形数据模型类

定义模型类封装矩形的坐标、样式和点击逻辑:

public class RectItem {
    private float left;
    private float top;
    private float right;
    private float bottom;
    private boolean isRound;
    private float roundRadiusX;
    private float roundRadiusY;
    private int color;
    private OnRectClickListener listener;

    public RectItem(float left, float top, float right, float bottom, boolean isRound, float roundRadiusX, float roundRadiusY, int color) {
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
        this.isRound = isRound;
        this.roundRadiusX = roundRadiusX;
        this.roundRadiusY = roundRadiusY;
        this.color = color;
    }

    public float getLeft() { return left; }
    public float getTop() { return top; }
    public float getRight() { return right; }
    public float getBottom() { return bottom; }
    public boolean isRound() { return isRound; }
    public float getRoundRadiusX() { return roundRadiusX; }
    public float getRoundRadiusY() { return roundRadiusY; }
    public int getColor() { return color; }
    public void setListener(OnRectClickListener listener) { this.listener = listener; }

    public boolean contains(float x, float y) {
        return x >= left && x <= right && y >= top && y <= bottom;
    }

    public void performClick() {
        if (listener != null) {
            listener.onRectClick(this);
        }
    }

    public interface OnRectClickListener {
        void onRectClick(RectItem rectItem);
    }
}

2. 改造自定义View支持动态绘制与点击

更新DrawView类,添加数据集合、绘制逻辑和触摸事件处理:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class DrawView extends View {
    private Paint mPaint;
    private List<RectItem> mRectList;
    private RectF mTempRectF;

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        mRectList = new ArrayList<>();
        mTempRectF = new RectF();
    }

    public DrawView(Context context) {
        super(context);
        init();
    }

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

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

    public void addRectItem(RectItem rectItem) {
        mRectList.add(rectItem);
        invalidate();
    }

    public void setRectList(List<RectItem> rectList) {
        mRectList.clear();
        if (rectList != null) {
            mRectList.addAll(rectList);
        }
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 如需绘制背景图片,在此处添加canvas.drawBitmap(...)逻辑

        for (RectItem item : mRectList) {
            mPaint.setColor(item.getColor());
            if (item.isRound()) {
                mTempRectF.set(item.getLeft(), item.getTop(), item.getRight(), item.getBottom());
                canvas.drawRoundRect(mTempRectF, item.getRoundRadiusX(), item.getRoundRadiusY(), mPaint);
            } else {
                canvas.drawRect(item.getLeft(), item.getTop(), item.getRight(), item.getBottom(), mPaint);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            float x = event.getX();
            float y = event.getY();
            // 倒序遍历确保上层矩形优先响应点击
            for (int i = mRectList.size() - 1; i >= 0; i--) {
                RectItem item = mRectList.get(i);
                if (item.contains(x, y)) {
                    item.performClick();
                    return true;
                }
            }
        }
        return super.onTouchEvent(event);
    }
}

3. 在Activity中使用自定义View

布局文件中添加DrawView:

<com.yourpackage.DrawView
    android:id="@+id/drawView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Activity中初始化数据并设置点击回调:

import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DrawView drawView = findViewById(R.id.drawView);

        List<RectItem> rectList = new ArrayList<>();
        // 添加圆角矩形
        RectItem roundRect = new RectItem(150, 150, 300, 300, true, 10, 10, Color.BLACK);
        roundRect.setListener(item -> Toast.makeText(MainActivity.this, "点击了圆角矩形", Toast.LENGTH_SHORT).show());
        rectList.add(roundRect);

        // 添加普通矩形
        RectItem normalRect = new RectItem(300, 300, 600, 600, false, 0, 0, Color.BLACK);
        normalRect.setListener(item -> Toast.makeText(MainActivity.this, "点击了普通矩形", Toast.LENGTH_SHORT).show());
        rectList.add(normalRect);

        drawView.setRectList(rectList);
    }
}

关键说明

  • 数据模型RectItem统一管理矩形的属性与点击行为,便于维护和扩展
  • 使用复用的RectF对象避免onDraw中频繁创建对象,优化绘制性能
  • 倒序遍历矩形列表,确保视觉上层的矩形优先响应点击,符合交互逻辑

内容的提问来源于stack exchange,提问作者Mohit Chaudhary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:15:47