【问题标题】:Method onTouchEvent not being called方法 onTouchEvent 未被调用
【发布时间】:2012-10-16 12:55:50
【问题描述】:

我的方法有问题

@Override
public boolean onTouchEvent(MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
}

永远不会被调用。任何想法为什么会这样?我正在构建一个谷歌的 API 4.0.3 应用程序,并且我正在尝试为我的 ViewFliper 启用滑动。但是,它无法工作,因为从不调用 touch。

代码:

 public class MainActivity extends SherlockMapActivity implements ActionBar.TabListener {

这就是我的活动声明。并检测我已经实现的滑动:

    SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener(){

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {

        float sensitvity = 50;
        if((e1.getX() - e2.getX()) > sensitvity){
            SwipeLeft();
        }else if((e2.getX() - e1.getX()) > sensitvity){
            SwipeRight();
        }

        return true;
    }

};
GestureDetector gestureDetector= new GestureDetector(simpleOnGestureListener);

谢谢。

编辑:

main.xml:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >

<ViewFlipper
    android:id="@+id/ViewFlipper"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff" >

    <include
        android:layout_height="match_parent"
        layout="@layout/mymain" />

    <include layout="@layout/secondmain" />
    <include layout="@layout/thirdmain" />
    <include layout="@layout/fourthmain" />
</ViewFlipper>
</LinearLayout>

Edit2:我所有包含的布局都实现了滚动视图。滚动是否有可能接受这些事件并处理它们?如果是,如何检测手势?

【问题讨论】:

  • 好的,现在我确定问题在于滚动视图句柄触摸,所以无论如何忽略它但滚动可用?

标签: android swipe touch-event


【解决方案1】:

所有手势和触摸事件都转到视图层次结构中可以处理的最低元素。 因此,如果您在包含的布局中有任何侦听器,您可以调用 ((TypeOfParrent)yourView.getParent()).onTouchEvent(event) 将事件委托给您想要的处理程序。

添加:我建议您使用ViewPager 翻转视图。 在 ViewPager 中你不需要实现你自己的 onGestureListener。

http://www.edumobile.org/android/android-beginner-tutorials/view-pager-example-in-android-development/

http://developer.android.com/reference/android/support/v4/view/ViewPager.html

【讨论】:

    【解决方案2】:

    好的,现在我确定问题是滚动视图句柄触摸,所以无论如何忽略它,但滚动可用?

    是的,这就是问题所在,当 android 处理触摸事件时,每个事件都会从子级传递到父级,所以首先它由 ViewFlipper 处理,然后再传递给 ScrollView。因此,您必须实现 getParent().requestDisallowInterceptTouchEvent(true) (请参阅ViewParent class)以使所有触摸事件都由 ViewFlipper 处理,然后简单地检测手势的方向(如果水平,则翻转视图),然后将触摸事件传递给ScrollView 或只是以编程方式滚动 ScrollView

    编辑:您也可以在 ViewFlipper 中实现 OnTouchListener 并在此侦听器中触发 GestureDetector.onTouchEvent(event),但这也需要将父视图的 requestDisallowInterceptTouchEvent 设置为 true

    【讨论】:

      【解决方案3】:

      我找到了一个完美的解决方案。我实现了新方法:

      @Override
      public boolean dispatchTouchEvent(MotionEvent event) {
      
          View v = getCurrentFocus();
          boolean ret = super.dispatchTouchEvent(event);
      

      现在一切正常!

      编辑:

      我的最终代码:

      @Override
      public boolean dispatchTouchEvent(MotionEvent event) {
          View v = getCurrentFocus();
          if (v instanceof EditText) {
              View w = getCurrentFocus();
              int scrcoords[] = new int[2];
              w.getLocationOnScreen(scrcoords);
              float x = event.getRawX() + w.getLeft() - scrcoords[0];
              float y = event.getRawY() + w.getTop() - scrcoords[1];
              if (event.getAction() == MotionEvent.ACTION_UP
                      && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w
                              .getBottom())) {
      
                  InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                  imm.hideSoftInputFromWindow(getWindow().getCurrentFocus()
                          .getWindowToken(), 0);
              }
          }
          boolean ret = super.dispatchTouchEvent(event);
          return ret;
      }
      

      【讨论】:

      • 谢谢,这是一个比@Chaosit 更简单的解决方案。
      • 嗨 - 你在哪里实现了这个新方法?它会返回什么?
      • 检查编辑的答案。我在 MainActivity.java 文件中实现了该功能。或者更好地在应用程序的主类中说。
      • 我在 webview 中使用了 onTouchEvent,似乎随着我的 WV 变得越来越复杂,onTouchEvent 方法变得越来越不稳定。 dispatchTouchEvent 可以很好地保证检测到触摸,但会吃掉 cpu,因为它在按住时会连续触发(我不认为 onTouchEvent 会连续触发)。
      【解决方案4】:

      正如我在 Gabrjan 的帖子中所写的那样,它在触摸屏幕时会连续触发,实际上有一种简单的方法可以只获取触地事件:

      @Override
      public boolean dispatchTouchEvent(MotionEvent event) {
          if (event.getAction() == MotionEvent.ACTION_DOWN) {
              System.out.println("TOUCH DOWN!");
              //set immersive mode here, or whatever...
          }
          return super.dispatchTouchEvent(event);
      } 
      

      这对我来说非常有用,无论何时触摸屏幕的任何部分,无论是哪个元素,都可以将 Android 置于沉浸式模式。但我不想重复设置沉浸式模式!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-18
        • 2014-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-25
        • 2021-08-12
        相关资源
        最近更新 更多