Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

detect if views are overlapping

Tags:

android

view

I have problem with drawing views on another size screens! I need method which has two parameters of View type. And return true if first view overlapping on second view, and false in another case!

enter image description here

and

enter image description here

like image 364
smail2133 Avatar asked Oct 08 '14 08:10

smail2133


4 Answers

You can also use Rect.intersect() to find overlapping views.

    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);
like image 122
Marcel Derks Avatar answered Oct 18 '22 09:10

Marcel Derks


Berserk thanks you for help! After some experiments I wrote method which detect view is overlapped or not for my case!

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);
    }
like image 31
smail2133 Avatar answered Oct 18 '22 09:10

smail2133


This is similar to the answer from Marcel Derks, but was written without the need for an additional import. It uses the basic code that forms Rect.intersect without creating the Rect objects.

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];
}

You are not required to force a view measurement, but it is done for good measure ;)

like image 6
Abandoned Cart Avatar answered Oct 18 '22 09:10

Abandoned Cart


In Kotlin, you can use the View class extension. It turns out a more compact solution:

// 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 ...
}
like image 6
Gregory Avatar answered Oct 18 '22 08:10

Gregory