问题 整个屏幕的onTouchListener


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

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

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

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

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

编辑:

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


13000
2018-04-13 12:12


起源



答案:


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

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

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

无论如何,回到我的活动中

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

然后我使用switch语句来处理下一个布局上的按钮。如果你需要它: 使用Switch语句处理按钮单击

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

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


8
2018-06-06 05:11



如果你的目标比1.6更新,你可以直接使用android:onClick =“functionname”而不是设置focusable并在代码中分配onclick监听器。 - Yenchi


答案:


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

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

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

无论如何,回到我的活动中

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

然后我使用switch语句来处理下一个布局上的按钮。如果你需要它: 使用Switch语句处理按钮单击

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

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


8
2018-06-06 05:11



如果你的目标比1.6更新,你可以直接使用android:onClick =“functionname”而不是设置focusable并在代码中分配onclick监听器。 - Yenchi


你有没有尝试过 onInterceptTouchEvent 在布局上?


3
2018-04-13 12:16



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


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

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

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


3
2017-10-17 06:19





触摸事件首先返回到子视图。如果为它们定义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();
    }

它有点复杂,但工作完美:)


1
2017-10-30 06:40