我有一个充满按钮的屏幕,但希望onTouch方法使用整个屏幕的坐标。我首先尝试使用带有onTouchListener的RelativeLayout,但从未设法让它与侦听器“连接”(即触摸屏幕时没有发生任何事情),我也尝试将ImageView放在屏幕顶部,然后使这个视图不可见
这最后一种方法对onClicks给出了正确的响应,但我从未设法让它变得不可见。
如果这是最好的解决方案,我非常怀疑,如何使ImageView完全不可见,而不会丢失其onTouchListener(我已尝试使用白色backgroundColor和setAlpha(0))。
我可以以某种方式使onTouchListener使用全局坐标对整个屏幕作出反应,同时屏幕显示(并改变)几个按钮(最好没有不可见的imageview)?
如果你不明白我的要求,请随时抱怨。我会尽力填补空白。
修改
我现在已经设法通过使用常规的onTouch方法解决了这个问题。我遇到了几个问题,让ACTION_DOWN和ACTION_MOVE激活按钮,但我终于让它工作了。对于阅读此内容的其他人:可能会使用onInterceptTouchEvent(但我从未弄清楚如何获取屏幕坐标而不是视图坐标)。
答案 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();
}
它有点复杂,但效果很好:)。