【问题标题】:onTouchListener for entire screen整个屏幕的 onTouchListener
【发布时间】:2011-08-04 16:10:31
【问题描述】:

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

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

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

我能否让 onTouchListener 在屏幕显示(和更改)几个按钮(最好没有不可见的图像视图)时使用全局坐标对整个屏幕做出反应?

如果您不明白我的要求,请随时投诉。我会根据需要尝试填补空白。

编辑:

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

【问题讨论】:

    标签: android view coordinates ontouchlistener


    【解决方案1】:

    对不起,如果我错了,但我相信我刚刚遇到了类似的问题。我想要一个显示图片的标题屏幕,并且在图片上显示“点击继续”或类似的文字。折腾了一下,发现布局可以点击。

        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

    似乎这也适用于其他布局,而且我对我的主布局没有任何看法。 (除非布局本身算作一个?)

    哈!刚刚意识到你说你找到了解决方案。愚蠢的时机。我将发布机会,这对某人有帮助,祝大家编码愉快。 :)

    【讨论】:

    • 如果你的target比1.6更新,你可以直接使用android:onClick="functionname"代替在代码中设置focusable和分配onclick监听器。
    【解决方案2】:

    你在布局上试过onInterceptTouchEvent吗?

    【讨论】:

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

    我用dispatchTouchEvent 解决了类似的问题。您可以将其视为 onTouchEvent 的直接替代品,但它始终会向您发送事件,即使它位于现有视图之上。

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

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

    【讨论】:

      【解决方案4】:

      touch 事件首先返回子视图。如果您为它们定义 onClick 或 onTouch 侦听器,则父视图(例如片段)将不会收到任何触摸侦听器。所以如果你想在这种情况下为片段定义滑动监听器,你必须在一个新的类中实现它:

          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();
          }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-19
        • 1970-01-01
        • 2011-11-28
        相关资源
        最近更新 更多