简体   繁体   English

Android:根视图(RelativeLayout)中的onTouchListener无法正常工作

[英]Android: onTouchListener in root view (RelativeLayout) isn't working

I'm developing an Android application and I'm trying to capture OnTouch events in my whole screen . 我正在开发一个Android应用程序,并且试图捕获整个屏幕上的 OnTouch events All my activities will have a header with two buttons and then a body that's going to change. 我所有的activities都有一个带有两个buttons的标题,然后是一个要更改的正文。

In the Activity I'm testing right now the body is a ListView , so the Activity has: 在我正在测试的Activity ,主体是ListView ,因此Activity具有:

-Two Buttons at the top of the screen. -屏幕顶部的两个Buttons

- ListView under those two buttons. -这两个按钮下的ListView

I want to capture onTouchEvents in the whole screen . 我想在整个屏幕上捕获onTouchEvents 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 . 我尝试将一个OnTouchListener设置为我的根RelativeLayout ,并为所有其他视图设置clickable = false和focusable = false,但是它不起作用: onTouch事件仅在我单击第一个按钮时触发

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: 这是@ 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 . 就像我说的, 仅当单击homeButton时 ,我的日志才会显示TOUCH。 Why is that? 这是为什么? What am I doing wrong? 我究竟做错了什么?

Thank you! 谢谢!

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? 为什么不只为您的RelativeLayout创建一个自定义视图来捕获触摸事件,然后您就可以用它做任何事情呢?

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. 然后,您可以通过在项目名称空间中查找该类,在XML中使用这种相对布局。 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. 您可以将其传递给其他活动,也可以使用它来调用其他方法,等等。有关如何使用自定义视图的更多信息, 请参见 android文档的这一部分。

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,而是在布局中只有一个ListView:

<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: 然后将标题布局添加到我的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. 现在,将onTouchListener设置为ListView,然后在整个屏幕上接收onTouch事件。

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. 我知道这是一个限制性解决方案,它不能用于复杂的布局,但可以在需要的屏幕中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM