0
\$\begingroup\$

I have a parent Activity which contains 2 views. One view is a custom view class, where I am overriding the onDraw method. This view contains an onTouchEvent function, which is checking for user clicks within the view.

Below this view I have another view, which is a view extending LinearLayout, which contains 9 buttons which are numbers to be selected by the user[I am basically trying to build a simple Sudoku game]. Now user clicks on my top view, which is the Sudoku Grid works fine, but it is calling the onTouchEvent of the top view, even when I click on the buttons within the bottom view keypad.

I have tried everything, from setFocusable(true), in the XML, in the constructor, from the parent activity. I even placed a onTouchListener on the keypad view. This listener is getting called when I click anywhere within the keypad view, except for on the buttons???

How can I detect a keyPress on the bottom view??

The bits of code

public class TrialBoard extends View{
@Override
public boolean onTouchEvent(MotionEvent event){
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
 selX = (int)event.getX();
 selY = (int)event.getY();
 Log.d(TTAG,"Touch X : " + selX + " Touch Y : " + selY);
 getRect(selX, selY);
 return true;
}else
if((event.getAction() == MotionEvent.ACTION_CANCEL)||(event.getAction()==MotionEvent.ACTION_OUTSIDE)){
 return false;//TRIED THIS BUT NOT WORKING
}else{
 return super.onTouchEvent(event);
}   

}

public class CustomKeypad extends LinearLayout {

@Override
public boolean onTouchEvent(MotionEvent event){
    if(event.getAction() == MotionEvent.ACTION_DOWN)
    {
        Log.d(KTAG,"Inside onTouch of keypad");
        return true;
    }else{
        return super.onTouchEvent(event);
    }
//NOT GETTING CALLED AT ALL 
}
}

public class TrialActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    Log.d(TRIALTAG,"Inside on create");
    setContentView(R.layout.trial_activity);
    keypadView = findViewById(R.id.keypad); 
    selNumber = 0;
    keypadView.bringToFront();
    keypadView.setFocusable(true);
    keypadView.setFocusableInTouchMode(true);
    keypadView.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event){
            Log.d(TRIALTAG,"Inside keypad view touched listener event");
            return true;
        }
    });
}
}

EDIT 2: My XML for keypad:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/keypad_background" >

<TableRow >
   <Button android:id="@+id/keypad_1"
       android:text="@string/key1"
       android:padding="2dp"
       android:onClick="num1Clicked"/>
   <Button android:id="@+id/keypad_2"
       android:text="@string/key2"
       android:padding="2dp"
        android:onClick="num2Clicked"/>
   <Button android:id="@+id/keypad_3"
       android:text="@string/key3" 
       android:padding="2dp"
        android:onClick="num3Clicked"/>
</TableRow>
<TableRow >
    <Button android:id="@+id/keypad_4"
        android:text="@string/key4"
        android:padding="2dp"
         android:onClick="num4Clicked" />
    <Button android:id="@+id/keypad_5"
        android:text="@string/key5"
        android:padding="2dp"
         android:onClick="num5Clicked" />
    <Button android:id="@+id/keypad_6"
        android:text="@string/key6"
        android:padding="2dp"
         android:onClick="num6Clicked" />
</TableRow>
<TableRow >
    <Button android:id="@+id/keypad_7"
        android:text="@string/key7"
        android:padding="2dp"
         android:onClick="num7Clicked" />
    <Button android:id="@+id/keypad_8"
        android:text="@string/key8"
        android:padding="2dp"
         android:onClick="num8Clicked" />
    <Button android:id="@+id/keypad_9"
        android:text="@string/key9"
        android:padding="2dp"
         android:onClick="num9Clicked" />
</TableRow>
</TableLayout>

I added the onClick later, coz I realized too late that this was a easier and saner way to get a button click event. I guess in a way I do deserve a flag down coz I should have remembered this, but I am still puzzled as to why it would not pick up the button click on the onTouchEvent.

\$\endgroup\$
7
  • \$\begingroup\$ Thanks for the response @Evan.but your comment is gone now..but yes that is precisely what I want to do. I want each child view to handle their own onTouchEvent functions. How can I differentiate which View was touched, when onTouchEvent in Parent is called? \$\endgroup\$
    – kvnam
    Apr 17, 2013 at 14:21
  • \$\begingroup\$ why did I get flagged down?? I'm still new here, so if you can let me know what I did wrong here I would appreciate it.. \$\endgroup\$
    – kvnam
    Apr 17, 2013 at 18:07
  • \$\begingroup\$ Can you post your XML? I think I know what's going on \$\endgroup\$
    – Ifrit
    Apr 21, 2013 at 12:44
  • \$\begingroup\$ @JaySoyer Have updated my XML. I added the clicks later, which is correctly picking up click events. So would I be correct to assume that the onTouchEvent does not pick up these events, coz the onClick of buttons are the only way to handle these?? \$\endgroup\$
    – kvnam
    Apr 22, 2013 at 14:23
  • \$\begingroup\$ Almost there. What does trial_activity look like? Is your custom view added dynamically? I'm trying to see if your custom view's bounds are simply over lapping the linear layout. Also, when you say top/bottom. You don't mean parent/child right? \$\endgroup\$
    – Ifrit
    Apr 22, 2013 at 15:33

2 Answers 2

2
\$\begingroup\$

It does not work because the buttons are Views too, just as LinearLayout and since they are on top they need their own "onTouchEvent" listener, which is onClick listener in their case. LinearLayout does not detect the touch on its children views because the children overtake the touch events for themselves.

But did you try to touch around the button? Then the LinearLayout's onTouchEvent may work.

\$\endgroup\$
2
  • \$\begingroup\$ You are correct, the onClick for the individual buttons works, but not the onTouch in the LinearLayout. onTouch on LinearLayout is triggered when clicking around the buttons though. Would it be correct to accept this as the answer, coz this is the solution that works in this case. \$\endgroup\$
    – kvnam
    Apr 26, 2013 at 6:18
  • \$\begingroup\$ Yes, it explains exactly what happens in this case and how to do it correctly. \$\endgroup\$
    – Lumis
    Apr 26, 2013 at 8:27
1
\$\begingroup\$

I believe the problem is that your custom view is somehow overlapping the linearlayout. An easy test is to add the following into your Drawable resource folder.

border.xml:

<solid android:color="@android:color/background_light" />

<stroke
    android:width="1dp"
    android:color="@android:color/black" />
</shape>

Then for your custom view, set it's background image to the border.xml resource. That background will draw a black outline around the perimeter of your View. You should also comment out the onDraw() method for this test.

\$\endgroup\$
1
  • \$\begingroup\$ I tried this, and the custom view is not overlapping the keypad view. Also the keypad view is included after the custom view, so I believe it is above the custom view, or so I have read. Thanks a lot for the answers though :) \$\endgroup\$
    – kvnam
    Apr 26, 2013 at 6:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .