方法onTouchEvent未被调用

37

我遇到了一个问题,我的方法

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

从未被调用。有什么想法吗?我正在构建一个Google API 4.0.3应用程序,并尝试为我的ViewFliper启用轻扫功能。然而,它无法工作,因为触摸从未被调用。

代码:

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

谢谢你。

edit:

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>

编辑2: 我包含的所有布局都已经实现了滚动视图。滚动视图是否会获取这些事件并处理它们?如果是那么如何检测手势呢?


好的,现在我确定问题是ScrollView处理触摸事件,有没有办法忽略它,同时保持滚动可用? - gabrjan
4个回答

55

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

@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提供的那个解决方案更简便的方案。 - Johannes Rudolph
你好 - 你在哪里实现了这个新方法?它返回什么? - Jona
检查编辑过的答案。我已经在我的MainActivity.java文件中实现了该函数。或者更好地说,在应用程序的主类中。 - gabrjan
我在使用onTouchEvent与我的webview时,似乎随着我的WV变得越来越复杂,onTouchEvent方法变得越来越不稳定。dispatchTouchEvent可以很好地保证触摸被检测到,但会消耗CPU,因为它在持续按住时不断触发(而我认为onTouchEvent不会连续触发)。 - Logic1
dispatchTouchEventViewPager 的官方方法吗? - IgorGanapolsky

15

就像我在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 设置为沉浸模式对我非常有用,无论哪个元素。但是我不希望重复设置沉浸模式!


6

好的,现在我确定问题是scrollview处理了触摸事件,有什么方法可以忽略这个问题但仍然可以滚动呢?

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

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


3
所有手势和触摸事件都会传递到视图层次结构中能够处理它的最低元素。 因此,如果你在包含的布局中有任何监听器,可以调用((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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接