【问题标题】:detect if views are overlapping检测视图是否重叠
【发布时间】:2014-10-08 08:47:30
【问题描述】:

我在其他尺寸的屏幕上绘制视图时遇到问题! 我需要具有两个 View 类型参数的方法。如果第一个视图与第二个视图重叠,则返回 true,在另一种情况下返回 false!

【问题讨论】:

  • 尝试使用不同的布局
  • 您是否针对不同的屏幕分辨率使用不同的布局?
  • 我不能改变布局,这是客户的愿望!
  • 不,使用一种布局!第一个视图的宽度可以动态变化

标签: android view


【解决方案1】:

您还可以使用 Rect.intersect() 来查找重叠视图。

    int[] firstPosition = new int[2];
    int[] secondPosition = new int[2];

    firstView.getLocationOnScreen(firstPosition);
    secondView.getLocationOnScreen(secondPosition);

    // Rect constructor parameters: left, top, right, bottom
    Rect rectFirstView = new Rect(firstPosition[0], firstPosition[1],
            firstPosition[0] + firstView.getMeasuredWidth(), firstPosition[1] + firstView.getMeasuredHeight());
    Rect rectSecondView = new Rect(secondPosition[0], secondPosition[1],
            secondPosition[0] + secondView.getMeasuredWidth(), secondPosition[1] + secondView.getMeasuredHeight());
    return rectFirstView.intersect(rectSecondView);

【讨论】:

  • 注意检查两个视图是否可见,否则返回false,否则getLocationOnScreen会抛出NullPointerException
【解决方案2】:

Berserk 感谢您的帮助! 经过一些实验,我编写了检测视图是否重叠的方法!

private boolean isViewOverlapping(View firstView, View secondView) {
        int[] firstPosition = new int[2];
        int[] secondPosition = new int[2];

        firstView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        firstView.getLocationOnScreen(firstPosition);
        secondView.getLocationOnScreen(secondPosition);

        int r = firstView.getMeasuredWidth() + firstPosition[0];
        int l = secondPosition[0];
        return r >= l && (r != 0 && l != 0);
    }

【讨论】:

  • 这是否涵盖了所有角落?
  • 是的,但我不检查它。这个解决方案对我有好处。为你试一试。
  • 这仅对始终水平对齐的两个视图有效,但当视图因水平分离而无法重叠时不起作用。简而言之,这只适用于测试垂直重叠。
  • @LoungeKatt 这个方法是测试水平重叠,而不是垂直重叠。请注意,我们正在处理宽度和 x 坐标。
  • @Elliott 不管怎样,它仅限于一个轴。这就是重点。
【解决方案3】:

这类似于Marcel Derks 的答案,但无需额外导入即可编写。它使用形成Rect.intersect 的基本代码,而不创建Rect 对象。

private boolean isViewOverlapping(View firstView, View secondView) {
    int[] firstPosition = new int[2];
    int[] secondPosition = new int[2];

    firstView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
    firstView.getLocationOnScreen(firstPosition);
    secondView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
    secondView.getLocationOnScreen(secondPosition);

    return firstPosition[0] < secondPosition[0] + secondView.getMeasuredWidth()
            && firstPosition[0] + firstView.getMeasuredWidth() > secondPosition[0]
            && firstPosition[1] < secondPosition[1] + secondView.getMeasuredHeight()
            && firstPosition[1] + firstView.getMeasuredHeight() > secondPosition[1];
}

您不需要强制进行视图测量,但这样做是为了进行良好的测量;)

【讨论】:

    【解决方案4】:

    在 Kotlin 中,您可以使用 View 类扩展。结果是一个更紧凑的解决方案:

    // Returns true if the view overlaps another view.
    // Additionally checks whether another view will overlap if it is shifted to delta values.
    fun View.isOverlap(other: View, deltaX: Int = 0, deltaY: Int = 0): Boolean {
        val thisXY  = IntArray(2).apply { getLocationOnScreen(this) }
        val otherXY = IntArray(2).apply {
            other.getLocationOnScreen(this)
            this[0] += deltaX
            this[1] += deltaY
        }
        return thisXY.let { Rect(it[0], it[1], it[0] + width, it[1] + height) }
            .intersect(otherXY.let { 
                Rect(it[0], it[1], it[0] + other.width, it[1] + other.height)
             })
    }
    
    // usage example:
    if (myView.isOverlap(otherView)) {
        // do something ...
    }
    

    【讨论】:

      【解决方案5】:

      似乎您正在询问解决问题的代码。我发布了我认为可能有效的逻辑:

      1. 创建一个函数,它将两个视图作为参数,并返回一个布尔值。
      2. 现在使用this 检查屏幕上两个视图的位置。它会让您了解它们是否重叠。
      3. 根据它返回真假。

      【讨论】:

      • 感谢您回答的帖子!我会像你说的那样尝试实施。如果解决方案效果很好,我会在这里写代码!
      【解决方案6】:

      以非常简单的方式帮助您。我将给出一个逻辑代码,它无疑会检测到两个碰撞的视图,即使它们正在移动。这适用于位图、图像视图以及您能想到的任何东西。在这里,这就是全部:

      //LET'S SAY WE DETECT IF PLAYER COLLIDES WITH ENEMY
      if((Math.abs(yourviewid.getY() - yoursecondviewid.getY()) < 75) 
           && (Math.abs(yourviewid.getX() - yoursecondviewid.getX()) < 75)){
          //DO YOUR STUFF HERE
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多