Android停止发送onTouch事件

4

我有一个自定义视图,希望处理触摸事件。特别是,拖动手指在视图上应该导致其内容滚动。为此,我实现了以下onTouchListener:

private OnTouchListener graphOnTouchListener = new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        System.out.println("onTouch called");
        System.out.println("view width: " + v.getWidth());
        System.out.println("view height: " + v.getHeight());
        System.out.println("view: " + v);

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                // First finger down
                System.out.println("ACTION_DOWN x: " + event.getX() + ", y: " + event.getY());
                startTouch(event.getX());
                break;
            case MotionEvent.ACTION_UP:
                // Last finger to be removed
                System.out.println("ACTION_UP x: " + event.getX() + ", y: " + event.getY());
                break;
            case MotionEvent.ACTION_MOVE:
                // A finger moves
                System.out.println("ACTION_MOVE x: " + event.getX() + ", y: " + event.getY());
                moveTouch(event.getX());
                break;
            default:
                break;
        }  

        // The event has been handled, so return true
        return true;
    }
};
这段代码在用户未移动手指时能够正常工作,但是当用户在视图上向上或向下移动手指时,触摸事件将停止发送(通过LogCat中缺少输出来证明)。然而,使用adb shell getevent仍然可以显示触摸移动产生的事件。

请问有谁能提供一些解决方法?

如请求所示,布局XML如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="#ffffff">
    <FrameLayout android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <ScrollView android:layout_width="fill_parent"
            android:layout_height="fill_parent" android:padding="10dip">
            <LinearLayout android:layout_width="fill_parent"
                android:layout_height="fill_parent" android:orientation="vertical">
                <com.graphlib.ShaderAreaGraphView
                    android:layout_width="fill_parent" android:layout_height="200dip"
                    android:id="@+id/activity_power_realtime" android:background="#000000" />
                <LinearLayout android:layout_width="fill_parent" android:id="@+id/linearLayout1" android:layout_height="wrap_content" android:gravity="center">
                    <Button android:text="&lt;&lt;" android:id="@+id/goBackwardsButton" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
                    <Button android:text="Zoom out" android:id="@+id/zoomOutButton" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
                    <Button android:text="Zoom in" android:id="@+id/zoomInButton" android:layout_width="wrap_content" android:layout_height="wrap_content" ></Button>
                    <Button android:text="&gt;&gt;" android:id="@+id/goForwardsButton" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
                </LinearLayout>
            </LinearLayout>
        </ScrollView>
    </FrameLayout>
</LinearLayout>

请展示一下布局XML。 - Lior Ohana
如果我理解正确,action_up 是指他们抬起手指?那么在此之后加上 break; 以确保在他们抬起手指后不会触发 action_move,这样不是更好吗? - yep
是的,可能吧,但我并不太在意。无论如何,我会编辑代码以消除干扰。 - Tim Timmingson
4个回答

3
您需要在每个case语句中编写break语句。否则,每个case语句都会被执行。
        case MotionEvent.ACTION_DOWN:
            // First finger down
            System.out.println("ACTION_DOWN x: " + event.getX() + ", y: " + event.getY());
            startTouch(event.getX());
            break;
        case MotionEvent.ACTION_UP:
            // Last finger to be removed
            System.out.println("ACTION_UP x: " + event.getX() + ", y: " + event.getY());
            break;
        case MotionEvent.ACTION_MOVE:
            // A finger moves
            System.out.println("ACTION_MOVE x: " + event.getX() + ", y: " + event.getY());
            moveTouch(event.getX());
            break;

您可以将其放入if ... else if条件语句中。

这没有任何影响,但我已经编辑了原始代码。 - Tim Timmingson
你面临的问题是什么?我测试了你的监听器,它完美地工作了。给我坐标、移动和松开时间。 - Pratik
向左右拖动一下,然后向上移动。这样做之后,左右移动将不会创建事件(至少在我正在测试的Nexus One或模拟器上是如此)。 - Tim Timmingson

2
原来问题出在视图嵌套了一个ScrollView中,移除ScrollView即可解决问题。

没错,我的自定义视图在垂直滚动视图中,并且在自定义视图中的onTouch事件是水平工作的,但当手指垂直移动时就停止了。 - Lumis

1
一个简单的解决方法是创建一个对滚动视图的引用,例如 myScrollView =(ScrollView)findViewById(R.id.myScrollView)。然后在 onTouchEvent 的 ACTION_DOWN 状态中:

myScrollView.requestDisallowInterceptTouchEvent(true);

而在ACTION_UP中

myScrollView.requestDisallowInterceptTouchEvent(false);


0
在你的 switch 底部,尝试添加以下内容。
default:
    break;

可能不是解决方案,但做这样的操作是一个好的练习。

不幸的是,这并没有解决任何问题。我已经按照您的建议更新了代码。 - Tim Timmingson

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