2011-04-13 70 views
11

我有一个充满按钮的屏幕,但是想让onTouch-method使用整个屏幕的坐标。我第一次尝试使用带有onTouchListener的RelativeLayout,但从未设法使其与监听器“连接”(即在触摸屏幕时没有发生任何事情),我也尝试将ImageView放在屏幕顶部,然后使该视图不可见。整个屏幕的onTouchListener

这最后一个方法给了onClicks正确的回应,但我从来没有设法让它看不见。

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

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

如果你不明白我在问什么,随时抱怨。我会尽量填补需要的空白。

编辑:

我现在已经成功使用常规onTouch的方法来解决这个问题。我遇到了几个问题,使ACTION_DOWN和ACTION_MOVE都激活了按钮,但我终于得到了它的工作。对于其他人阅读:onInterceptTouchEvent可能会被使用(但我从来没有想出如何获得屏幕坐标,而不是视图坐标)。

回答

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

似乎这应该与其他布局,以及我的主要布局没有字面上任何意见。 (除非布局本身算作一个?)

哈!刚才意识到你说你找到了解决方案。愚蠢的时机。我会发布这个帮助别人的机会,让每个人都快乐。 :)

+2

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

3

您是否在版面上尝试过onInterceptTouchEvent

+0

Dsouza我尝试过,但并不满足。我现在通过使用常规的onTouch方法设法解决了这个问题。我遇到了几个问题,使ACTION_DOWN和ACTION_MOVE都激活了按钮,但我终于得到了它的工作。对于其他人阅读:onInterceptTouchEvent可能会被使用(但我从来没有想出如何获得屏幕坐标,而不是视图坐标)。 – keyser 2011-04-17 16:03:07

3

我用dispatchTouchEvent一个类似的问题。您可以认为它是onTouchEvent的直接替代品,只是它始终向您发送一个事件,即使它是在现有视图之上。

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

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

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。它的重要性在于,如果我们不这样做,有时候子视图可能会接收事件,而且对于子视图(例如)的片段和onClick都会运行并导致一些问题。 使得这个类后,你必须改变你的片段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(); 
    } 

这是一个有点复杂,但完美的作品:)