tripleblep
tripleblep

Reputation: 540

Weird issue with changing view background color

I have a bunch of views with solid-colored backgrounds. These views can be dragged around; I would like to change the background depending on whether or not a view intersects with another view. Below is the code I'm using in MotionEvent.ACTION_UP

// Get all children of the parent view
for(int i = 0; i < ((ViewGroup) getParent()).getChildCount(); i++) {
    View childOne = ((ViewGroup) getParent()).getChildAt(i);
    // For each child, check for intersection with siblings
    for(int z = 0; z < ((ViewGroup) getParent()).getChildCount(); z++) {
        View childTwo = ((ViewGroup) getParent()).getChildAt(z);
        if(childOne == childTwo)
            continue;
        Rect recOne = new Rect();
        childOne.getHitRect(recOne);
        Rect recTwo = new Rect();
        childTwo.getHitRect(recTwo);
        if (Rect.intersects(recOne, recTwo)) {
            ((EditView) childTwo).setPaintColor(Color.RED);
        } else {
            ((EditView) childTwo).setPaintColor(Color.GREEN);
        }
    }
}

This should loop through each view and check if the view intersects with another view. If so, change the background color of the intersecting view. All views extend the EditView class, which handles its own touch events. I should also mention that MotionEvent.ACTION_DOWN brings the touched to the "front", so the user can easily manipulate it if it's hidden behind another view. Below explains how it currently works:

example

These views are laid out using RelativeLayout. I'm beginning to think that the ordering of the views may be the cause of this, but I'm not sure.

Upvotes: 0

Views: 64

Answers (1)

ifeomaro
ifeomaro

Reputation: 2764

In my opinion, you need to modify your for loop slightly. The reason is because if childOne intersects with childTwo, it means that childTwo also intersects with childOne, (so there's no need to check twice). And since both views intersect, I would change the colors of both views at the same time. So I would modify your code this way:

// Get all children of the parent view
for(int i = 0; i < ((ViewGroup) getParent()).getChildCount(); i++) {
    View childOne = ((ViewGroup) getParent()).getChildAt(i);
    // For each child, check for intersection with siblings
    // start z at index (i+1)
    for(int z = i+1; z < ((ViewGroup) getParent()).getChildCount(); z++) {
        View childTwo = ((ViewGroup) getParent()).getChildAt(z);
        Rect recOne = new Rect();
        childOne.getHitRect(recOne);
        Rect recTwo = new Rect();
        childTwo.getHitRect(recTwo);
        if (Rect.intersects(recOne, recTwo)) {
            // both views intersect, change both to red
            ((EditView) childOne).setPaintColor(Color.RED);
            ((EditView) childTwo).setPaintColor(Color.RED);
        } else {
            // both views do not intersect, change both to green
            ((EditView) childOne).setPaintColor(Color.GREEN);
            ((EditView) childTwo).setPaintColor(Color.GREEN);
        }
    }
}

I hope this helps.

Upvotes: 1

Related Questions