我有一个充满按钮的屏幕,但希望onTouch方法使用整个屏幕的坐标。我首先尝试将RelativeLayout与onTouchListener一起使用,但从未设法使其与侦听器“连接”(即触摸屏幕时没有发生任何事情),我也尝试将ImageView放在屏幕顶部,然后使此视图不可见。
最后一种方法对onClicks给出了正确的响应,但我从未设法让它变得不可见。
如果这是最好的解决方案,我非常怀疑,如何使ImageView完全不可见,而不会丢失其onTouchListener(我已经尝试了白色backgroundColor和setAlpha(0))。
我可以以某种方式使onTouchListener使用全局坐标对整个屏幕作出反应,同时屏幕显示(并改变)几个按钮(最好没有不可见的imageview)?
如果你不明白我的要求,请随时抱怨。我会尽力填补空白。
编辑:
我现在设法通过使用常规onTouch方法解决问题。我遇到了几个问题,让ACTION_DOWN和ACTION_MOVE激活按钮,但我终于让它工作了。对于阅读此内容的其他人:可能会使用onInterceptTouchEvent(但我从未弄清楚如何获取屏幕坐标而不是视图坐标)。
对不起,如果我错了,但我相信我遇到了类似的问题。我想要一个标题画面,显示一张图片,并在图片上写着“点击继续”或类似的东西。我搞砸了一下,发现你可以点击布局。
android:focusable="true"
android:id="@+id/titlescreenframe">
是我的xml文件中的布局。背景图片只是在背景属性中(我意识到你没有使用图像)
无论如何,回到我的活动中
private FrameLayout fl;
...
fl = (FrameLayout)findViewById(R.id.titlescreenframe);
fl.setOnClickListener(this);
然后我使用switch语句来处理下一个布局上的按钮。如果你需要它: 使用Switch语句处理按钮单击
似乎这应该与其他布局一起使用,而且我的主要布局上没有任何视图。 (除非布局本身算作一个?)
哈!刚刚意识到你说你找到了解决方案。愚蠢的时机。我会发布这个帮助某人的机会,很高兴为每个人编码。 :)
对不起,如果我错了,但我相信我遇到了类似的问题。我想要一个标题画面,显示一张图片,并在图片上写着“点击继续”或类似的东西。我搞砸了一下,发现你可以点击布局。
android:focusable="true"
android:id="@+id/titlescreenframe">
是我的xml文件中的布局。背景图片只是在背景属性中(我意识到你没有使用图像)
无论如何,回到我的活动中
private FrameLayout fl;
...
fl = (FrameLayout)findViewById(R.id.titlescreenframe);
fl.setOnClickListener(this);
然后我使用switch语句来处理下一个布局上的按钮。如果你需要它: 使用Switch语句处理按钮单击
似乎这应该与其他布局一起使用,而且我的主要布局上没有任何视图。 (除非布局本身算作一个?)
哈!刚刚意识到你说你找到了解决方案。愚蠢的时机。我会发布这个帮助某人的机会,很高兴为每个人编码。 :)
我用了 dispatchTouchEvent 对于类似的问题。您可以将其视为替代品 onTouchEvent
,除非它总是向您发送一个事件,即使它是在现有视图上。
如果您正在处理事件,则返回true,否则请务必致电 super.dispatchTouchEvent()
并返回其结果。
至于获取屏幕坐标 - 只需调用MotionEvent即可 getRawX()
和 getRawY()
而不是 getX()
和 getY()
。这些是绝对屏幕坐标,包括操作栏和所有。如果你想交叉引用那些有视图的, getLocationOnScreen 可能是最简单的解决方案。
触摸事件首先返回到子视图。如果为它们定义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();
}
它有点复杂,但工作完美:)