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

Android Studio中如何判断路径是否处于矩形范围内?

嘿,这个需求我之前做手绘类应用时刚好碰到过,给你分享几个实用的实现思路,核心就是判断Path和选择矩形的关系,分两种场景给你讲:

第一步:先搞定选择矩形的绘制与获取

首先你得在onTouchEvent里处理用户的按压拖动,生成正确的选择矩形,还要注意处理用户从右下往左上拖动的情况,确保矩形的left<=right、top<=bottom:

private PointF downTouchPoint = new PointF();
private RectF selectionRect = new RectF();

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downTouchPoint.set(event.getX(), event.getY());
            selectionRect.setEmpty();
            break;
        case MotionEvent.ACTION_MOVE:
            // 构建正确的选择矩形,兼容任意拖动方向
            selectionRect.set(
                Math.min(downTouchPoint.x, event.getX()),
                Math.min(downTouchPoint.y, event.getY()),
                Math.max(downTouchPoint.x, event.getX()),
                Math.max(downTouchPoint.y, event.getY())
            );
            invalidate(); // 重绘显示选框
            break;
        case MotionEvent.ACTION_UP:
            // 触发路径选择逻辑
            selectAndRemovePaths(selectionRect);
            selectionRect.setEmpty();
            invalidate();
            break;
    }
    return true;
}

别忘了在onDraw里把选择矩形画出来,让用户能看到自己选的范围:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 绘制所有路径
    for (Path path : paths) {
        canvas.drawPath(path, mPaint);
    }
    // 绘制半透明的选择框
    if (!selectionRect.isEmpty()) {
        Paint selectPaint = new Paint();
        selectPaint.setColor(Color.argb(128, 0, 153, 204));
        selectPaint.setStyle(Paint.Style.STROKE);
        selectPaint.setStrokeWidth(2f);
        canvas.drawRect(selectionRect, selectPaint);
    }
}
第二步:核心逻辑——判断Path是否在选择矩形内

这里分两种需求场景,你可以根据自己的产品需求选:

场景1:路径的整个包围盒都在选框内才选中

这种方法简单高效,适合要求“完全选中”的场景。用Path.computeBounds()获取路径的最小包围矩形,再判断这个矩形是否被选择矩形完全包含:

private void selectAndRemovePaths(RectF selectRect) {
    List<Path> pathsToDelete = new ArrayList<>();
    RectF pathBounds = new RectF();

    for (Path path : paths) {
        path.computeBounds(pathBounds, true);
        // 判断路径的包围盒是否完全在选择矩形内
        if (selectRect.contains(pathBounds)) {
            pathsToDelete.add(path);
        }
    }

    // 批量移除选中的路径
    paths.removeAll(pathsToDelete);
}

场景2:路径和选框有交集就选中(更精准)

如果需要只要路径有一部分在选框里就选中,推荐用Path的布尔运算来判断,精度更高:

private void selectAndRemovePaths(RectF selectRect) {
    List<Path> pathsToDelete = new ArrayList<>();
    Path rectPath = new Path();
    rectPath.addRect(selectRect, Path.Direction.CW);

    for (Path path : paths) {
        // 复制原路径,避免修改原数据
        Path tempPath = new Path(path);
        // 判断两个路径是否有交集
        if (tempPath.op(rectPath, Path.Op.INTERSECT)) {
            pathsToDelete.add(path);
        }
    }

    paths.removeAll(pathsToDelete);
}
一些额外的优化建议
  1. 如果你的路径数量特别多,遍历判断可能会卡顿,可以把判断逻辑放到子线程处理,处理完后再用post()回到主线程更新UI和重绘。
  2. 如果画布有平移、缩放等变换,记得把触摸坐标转换成画布的实际坐标(比如用Matrix的逆变换处理),不然选择范围会和视觉上的不一致。
  3. 可以给选中的路径加个高亮效果,比如绘制时用不同颜色的Paint,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:31:11