整个屏幕的onTouchListener

时间:2011-04-13 12:12:52

标签: android view coordinates ontouchlistener

我有一个充满按钮的屏幕,但希望onTouch方法使用整个屏幕的坐标。我首先尝试使用带有onTouchListener的RelativeLayout,但从未设法让它与侦听器“连接”(即触摸屏幕时没有发生任何事情),我也尝试将ImageView放在屏幕顶部,然后使这个视图不可见

这最后一种方法对onClicks给出了正确的响应,但我从未设法让它变得不可见。

如果这是最好的解决方案,我非常怀疑,如何使ImageView完全不可见,而不会丢失其onTouchListener(我已尝试使用白色backgroundColor和setAlpha(0))。

我可以以某种方式使onTouchListener使用全局坐标对整个屏幕作出反应,同时屏幕显示(并改变)几个按钮(最好没有不可见的imageview)?

如果你不明白我的要求,请随时抱怨。我会尽力填补空白。

修改

我现在已经设法通过使用常规的onTouch方法解决了这个问题。我遇到了几个问题,让ACTION_DOWN和ACTION_MOVE激活按钮,但我终于让它工作了。对于阅读此内容的其他人:可能会使用onInterceptTouchEvent(但我从未弄清楚如何获取屏幕坐标而不是视图坐标)。

4 个答案:

答案 0 :(得分:8)

对不起,如果我错了,但我相信我遇到了类似的问题。我想要一个标题画面,显示一张图片,并在图片上写着“点击继续”或类似的东西。我搞砸了一下,发现你可以点击布局。

    android:focusable="true" 
    android:id="@+id/titlescreenframe">

在我的xml文件中,用于我的布局。背景图像只是在背景属性中(我意识到你没有使用图像)

无论如何,回到我的活动

    private FrameLayout fl;
    ...
    fl = (FrameLayout)findViewById(R.id.titlescreenframe);
    fl.setOnClickListener(this);

然后我使用switch语句来处理下一个布局上的按钮。如果您需要,请在此处:Using Switch Statement to Handle Button Clicks

似乎这应该适用于其他布局,而且我的主要布局上没有任何视图。 (除非布局本身算作一个?)

哈!刚刚意识到你说你找到了解决方案。愚蠢的时机。我会发布这个帮助某人的机会,很高兴为每个人编码。 :)

答案 1 :(得分:3)

您是否在布局上尝试了onInterceptTouchEvent

答案 2 :(得分:3)

我使用dispatchTouchEvent来解决类似的问题。您可以将其视为onTouchEvent的替代品,除非它始终向您发送一个事件,即使它是在现有视图上。

如果您正在处理该事件,则返回true,否则,请务必致电super.dispatchTouchEvent()并返回其结果。

至于获取屏幕坐标 - 只需调用MotionEvent的getRawX()getRawY()而不是getX()getY()。这些是绝对屏幕坐标,包括操作栏和所有。如果您想交叉引用带有视图的内容,getLocationOnScreen可能是最简单的解决方案。

答案 3 :(得分:1)

首先触摸事件返回子视图。如果为它们定义onClick或onTouch侦听器,则parnt视图(例如片段)将不会接收任何触摸侦听器。因此,如果要在这种情况下为片段定义滑动侦听器,则必须在新类中实现它:

    package com.neganet.QRelations.fragments;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;

public class SwipeListenerFragment extends FrameLayout {
    private float x1,x2;
    static final int MIN_DISTANCE=150;
    private onSwipeEventDetected mSwipeDetectedListener;


    public SwipeListenerFragment(Context context) {
        super(context);
    }

    public SwipeListenerFragment(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeListenerFragment(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean result=false;
        switch(ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                x1 = ev.getX();
                break;
            case MotionEvent.ACTION_UP:
                x2 = ev.getX();
                float deltaX = x2 - x1;
                if (Math.abs(deltaX) > MIN_DISTANCE)
                {
                    if(deltaX<0)
                    {
                        result=true;
                        if(mSwipeDetectedListener!=null)
                            mSwipeDetectedListener.swipeLeftDetected();

                    }else if(deltaX>0){
                        result=true;
                        if(mSwipeDetectedListener!=null)
                            mSwipeDetectedListener.swipeRightDetected();
                    }
                }
                break;
        }
        return result;
    }

    public interface onSwipeEventDetected
    {
        public void swipeLeftDetected();
        public void swipeRightDetected();

    }

    public void registerToSwipeEvents(onSwipeEventDetected listener)
    {
        this.mSwipeDetectedListener=listener;
    }
}

你可以完全像这样为其他类型的布局制作工具。这个类可以检测左右滑动,特别是在检测后返回onInterceptTouchEvent为true。它很重要,因为如果我们不这样做,有时候子视图可能会收到事件,并且Swipe for fragment和onClick for child view(例如)都会运行并导致一些问题。 创建此类之后,您必须更改片段xml文件:

    <com.neganet.QRelations.fragments.SwipeListenerFragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:id="@+id/main_list_layout"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:layout_height="match_parent" tools:context="com.neganet.QRelations.fragments.mainList"
    android:background="@color/main_frag_back">

    <!-- TODO: Update blank fragment layout -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/farazList"
        android:scrollbars="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="left|center_vertical" />
</com.neganet.QRelations.fragments.SwipeListenerFragment>

你看到开始标记是我们创建的类。现在在片段类中:

            View view=inflater.inflate(R.layout.fragment_main_list, container, false);
        SwipeListenerFragment tdView=(SwipeListenerFragment) view;
        tdView.registerToSwipeEvents(this);


and then Implement SwipeListenerFragment.onSwipeEventDetected in it:

        @Override
    public void swipeLeftDetected() {
        Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void swipeRightDetected() {
        Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show();
    }

它有点复杂,但效果很好:)。