Question

I'm developing an Android application and I'm trying to capture OnTouch events in my whole screen. All my activities will have a header with two buttons and then a body that's going to change.

In the Activity I'm testing right now the body is a ListView, so the Activity has:

-Two Buttons at the top of the screen.

-ListView under those two buttons.

I want to capture onTouchEvents in the whole screen. I tried setting an OnTouchListener to my root RelativeLayout and set clickable=false and focusable=false to all the other views, but it's not working: the onTouch event is only triggered when I click the first button.

This is my layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <include
        layout="@layout/header"
        android:clickable="false"
        android:focusable="false" />

    <ListView
        android:id="@+id/lvLocations"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/header_layout"
        android:clickable="false"
        android:focusable="false" />

</RelativeLayout>

This is the content of @layout/header:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/header_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="false"
    android:focusable="false"
    android:weightSum="5" >

    <Button
        android:id="@+id/homeButton"
        android:layout_width="0dip"
        android:layout_height="50dp"
        android:layout_marginRight="5dp"
        android:layout_weight="4"
        android:clickable="false"
        android:focusable="false"
        android:onClick="Home"
        android:text="@string/home" />

    <ImageButton
        android:id="@+id/speechButton"
        android:layout_width="0dip"
        android:layout_height="50dp"
        android:layout_weight="1"
        android:clickable="false"
        android:focusable="false"
        android:onClick="ClickMediaButton"
        android:src="@drawable/micro" />

</LinearLayout>

And this is the code I'm using:

    findViewById(R.id.root).setOnTouchListener(new OnTouchListener() {          
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.d("MACT", "TOUCH!");
        }
    });

Like I said, my log shows TOUCH only when the homeButton is clicked. Why is that? What am I doing wrong?

Thank you!

Was it helpful?

Solution 2

I finally managed to solve it, and to do it I redesigned my layout. Now instead of having a header and a ListView I just have a ListView in my layout:

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/myList"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Then I add the header layout to my ListView:

View header = (View)getLayoutInflater().inflate(R.layout.header,null);
mList.addHeaderView(header);

Now I set the onTouchListener to the ListView and voilà, I receive the onTouch events in the whole screen.

I know this is a restrictive solution and it can't be used with complex layouts, but I can use it in the screens I needed it.

OTHER TIPS

Why not just create a custom view for your RelativeLayout that catches the touch event and then you can do whatever you want with it?

public class CustomRelativeLayout extends RelativeLayout{

    CustomRelativeLayout(Context context, AttributeSet attrs){
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev){
        //handle touch event
        return true;
    }
}

You would then use this relative layout in your XML by looking for that class in your projects namespace. You can of course add whatever modifiers you want but here's an example of what it looks like.

<com.example.whatever.your.project.CustomRelativeLayout
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"/>

Once you catch the touch you can do whatever you want with it. You can pass it to other activities, you can use it to call other methods, etc. For more on how to use custom views see this part of the android docs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top