0

In my app activity, I have 8 buttons, 1 textView , 2 relative layouts and 1 linear layout(parent).

This is what it looks like:

Here is the structure:

< Linear Layout >
.........< Relative Layout 1 .....weight= 0.5>
.................< Button 1 >
.................< Button 2 >
.................< Button 3 >
.................< Button 4 >
.................< TextView "Touch a button">
.........< \Relative Layout>

.........< Relative Layout 2 .....weight= 0.5>
.................< Button 5 >
.................< Button 6 >
.................< Button 7 >
.................< Button 8 >
.........< \Relative Layout>
< Linear Layout >

As you might have guessed from the title, I am trying to get the coordinates of all the 8 buttons and detect if my finger is over any one of them while it moves through the screen.

I am able to get the coordinates of the buttons using the code given below but its not working properly. According to my code, the buttons should change their background color to red once they have been touched or hovered over. But what's happening is that buttons 5,6,7 and 8 do not recognize my touch and 1,2,3,4 do recognize it but they change their parallel button's color too. For instance if I touch B8, nothing happens but if I touch B4 it changes color along with B8.

To better explain I have put an image below. This image represents what happens when I touch B4:

Why is this happening? What maybe the prob? Please help me solve it.

Here is my code: Main_Activity.java

public class MainActivity extends Activity {

MyButton b1, b2, b3, b4,b5,b6,b7,b8;

private TextView buttonIndicator;
private LinearLayout touchview;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    buttonIndicator = (TextView) findViewById(R.id.textView);
    touchview = (LinearLayout) findViewById(R.id.linearlayout);

    b1 = (MyButton) findViewById(R.id.button1);
    b2 = (MyButton) findViewById(R.id.button2);
    b3 = (MyButton) findViewById(R.id.button3);
    b4 = (MyButton) findViewById(R.id.button4);
    b5 = (MyButton) findViewById(R.id.button5);
    b6 = (MyButton) findViewById(R.id.button6);
    b7 = (MyButton) findViewById(R.id.button7);
    b8 = (MyButton) findViewById(R.id.button8);

    RelativeLayout touch1 = (RelativeLayout) findViewById(R.id.touchview1);
    RelativeLayout touch2 = (RelativeLayout) findViewById(R.id.touchview2);
    touch1.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            return false; // To pass touch event to linear layout parent
        }
    });
    touch2.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            return false; // To pass touch event to linear layout parent
        }
    });
}

@Override
protected void onResume() {
    super.onResume();

    touchview.setOnTouchListener(new View.OnTouchListener() {

        private boolean isInside = false;

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            int x = (int) event.getX();
            int y = (int) event.getY();

            if (isPointWithin(x, y, b1.getLeft(), b1.getRight(), b1.getTop(),b1.getBottom())) {
                b1.setBackgroundColor(Color.RED);
                buttonIndicator.setText("Button 1");
            }

            if (isPointWithin(x, y, b2.getLeft(), b2.getRight(), b2.getTop(),b2.getBottom())) {
                b2.setBackgroundColor(Color.RED);
                buttonIndicator.setText("Button 2");
            }

            if (isPointWithin(x, y, b3.getLeft(), b3.getRight(), b3.getTop(),b3.getBottom())) {
                b3.setBackgroundColor(Color.RED);
                buttonIndicator.setText("Button 3");
            }

            if (isPointWithin(x, y, b4.getLeft(), b4.getRight(), b4.getTop(),b4.getBottom())) {
                b4.setBackgroundColor(Color.RED);
                buttonIndicator.setText("Button 4");
            }

            if (isPointWithin(x, y, b5.getLeft(), b5.getRight(), b5.getTop(),b5.getBottom())) {
                b5.setBackgroundColor(Color.RED);
                buttonIndicator.setText("Button 5");
            }

            if (isPointWithin(x, y, b6.getLeft(), b6.getRight(), b6.getTop(),b6.getBottom())) {
                b6.setBackgroundColor(Color.RED);
                buttonIndicator.setText("Button 6");
            }

            if (isPointWithin(x, y, b7.getLeft(), b7.getRight(), b7.getTop(),b7.getBottom())) {
                b7.setBackgroundColor(Color.RED);
                buttonIndicator.setText("Button 7");
            }

            if (isPointWithin(x, y, b8.getLeft(), b8.getRight(), b8.getTop(),b8.getBottom())) {
                b8.setBackgroundColor(Color.RED);
                buttonIndicator.setText("Button 8");
            }

            return true;
        }

    });

  }

    //The boolean below determines the exact position of the finger on the screen 
    static boolean isPointWithin(int x, int y, int x1, int x2, int y1, int y2) {
    return (x <= x2 && x >= x1 && y <= y2 && y >= y1);
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1.0"
android:background="#ffffff" >

<RelativeLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:id="@+id/touchview1"
    android:layout_weight="0.5">

<com.example.coordinates.MyButton
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:text="B1"
    android:layout_marginBottom="10dp"
    android:textColor="#000000" />

<com.example.coordinates.MyButton
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_below="@+id/button1"
    android:layout_marginBottom="10dp"
    android:text="B2"
    android:textColor="#000000" />

<com.example.coordinates.MyButton
    android:id="@+id/button3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_below="@+id/button2"
    android:text="B3"
    android:layout_marginBottom="10dp"
    android:textColor="#000000" />

<com.example.coordinates.MyButton
    android:id="@+id/button4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_below="@+id/button3"
    android:text="B4"
    android:textColor="#000000" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Touch a button"
        android:layout_marginLeft="10dp"
        android:layout_marginBottom="10dp"
        android:id="@+id/textView"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true" />
</RelativeLayout>

<RelativeLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:id="@+id/touchview2"
    android:layout_weight="0.5">


    <com.example.coordinates.MyButton
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="B5"
        android:layout_marginBottom="10dp"
        android:textColor="#000000" />

    <com.example.coordinates.MyButton
        android:id="@+id/button6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/button5"
        android:layout_marginBottom="10dp"
        android:text="B6"
        android:textColor="#000000" />

    <com.example.coordinates.MyButton
        android:id="@+id/button7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/button6"
        android:text="B7"
        android:layout_marginBottom="10dp"
        android:textColor="#000000" />

    <com.example.coordinates.MyButton
        android:id="@+id/button8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/button7"
        android:text="B8"
        android:textColor="#000000" />

    </RelativeLayout>

</LinearLayout>

MyButton.java

public class MyButton extends Button {
//I am using cutom Button to avoid ontouch for buttons and return false
public MyButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
}

public MyButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}

public MyButton(Context context) {
    super(context);
    // // TODO Auto-generated constructor stub
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub
    // return super.onTouchEvent(event);
    return false;
}

}

I have tried my best to explain my problem. Please help me!
Thank you all very very much.

Edit : I was suggested to use View.getLocationOnScreen(). Can anyone please explain me how to get (x1 and x2) & (y1 and y2) coordinates with the help of this method? I think the image below explains it better!

Atul O Holic
  • 6,692
  • 4
  • 39
  • 74
Chinmay Dabke
  • 5,070
  • 11
  • 40
  • 63
  • Why dont you try onCLickListener or onTouchlistener on your buttons directly and change their background when the event is performed? If in case your requirement are more than this then please pardon me. – Atul O Holic Feb 21 '14 at 13:23
  • @Atul, Yes my requirements are much more than this. No prob. Please help me find a solution for it! – Chinmay Dabke Feb 21 '14 at 13:24
  • See if this helps. http://stackoverflow.com/questions/3619693/getting-views-coordinates-relative-to-the-root-layout – Atul O Holic Feb 21 '14 at 13:28
  • I see you have tried getLocationOnScreen, but have you tried getLocationOnWindow as well. THese are the two suggested by the Romain Guy here - http://stackoverflow.com/questions/2224844/how-to-get-the-absolute-coordinates-of-a-view. Also, I believe to get all the 4 co-ordinates as above image, you will have to combine the methods giving the x1 and y1 of the View with the methods providing you with the size of your View. – Atul O Holic Feb 21 '14 at 13:50
  • It's too confusing. Can you please write this code with reference to my button in my code and post it here? That would be great. – Chinmay Dabke Feb 21 '14 at 13:52

2 Answers2

1

getLeft() returns left border relative to parent. You should recursively add getLeft() of all parents as well.

Explained differently: both b4 and b8 return the same number for getLeft() call. if you want their absolute screen coordinates, see

How to get the absolute coordinates of a view

int pos[] = new int[2];
button.getLocationOnScreen(pos);
int x1 = pos[0], y1 = pos[1];
int x2 = x1 + button.getWidth();
int y2 = y1 + button.getHeight();
Community
  • 1
  • 1
velis
  • 8,747
  • 4
  • 44
  • 64
  • So should i use `View.getLocationOnScreen();`? But then how do i get all the 4 coordinates? Can you please write the code in reference to my question? – Chinmay Dabke Feb 21 '14 at 13:23
  • 1
    Sorry about not answering sooner, was sleeping :). Anyway: getLocationOnScreen takes an array of two integers which receive x and y coordinates respectively. So you get X1, Y1. to get X2, Y2, just compute X2 = X1 + getWidth() and Y2 = Y1 + getHeight() – velis Feb 22 '14 at 08:32
  • This is because your mainview.onClick also returns X and Y relative to that view.You have to translate them to screen coordinates as well. The statusbar and probably also app title area are not accounted for in the onClick coordinates. Alternatively, use getLocationInWindow() for buttons – velis Feb 22 '14 at 09:41
0

check this code

private boolean checkInterSection(View view, int rawX, int raxY) {
int[] location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
int width = view.getWidth();
int height = view.getHeight();
//Check the intersection of point with rectangle achieved 
return (!(rawX < x || rawY > x + width || rawY < y || rawY > y + height)); }

for(int i = 0; i < touchview.getChildCount(); i++){
if(checkInterSection(touchview.getChildAt(i), event.getRawX(), event.getRawY())){
    if(checkInterSection(touchview.getChildAt(i), event.getRawX(), event.getRawY())){
        ((Button)touchview.getChildAt(i)).setBackgroundColor(Color.BLUE);// Type casting may not be required 
    }else{
        ((Button)touchview.getChildAt(i)).setBackgroundColor(Color.WHITE);
    }
    break;
} }

From this link. And check the Answer posted by @Rajesh CP. I guess this is what exactly you need hope this helps you.

Community
  • 1
  • 1
i.n.e.f
  • 1,773
  • 13
  • 22