开发者

Android stops sending onTouch events

I have a custom view which I wish to handle touch events for. In particular, dragging a finger over the view should cause its contents to scroll. To do this, I have implemented the following 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;
    }
};

This works as expected, unless the user moves their finger up or down while on the view. At this point, touch events stop being sent (as evidenced by a lack of output in LogCat). However, using adb shell getevent still shows events being generated by touch movement.

Can anyone suggest how I can rectify this?

As requested, the layout XML looks like:

<?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>


you need write the break statement in each case. otherwise every case are executed.

        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;

or you can put into the if ... else if condition


It turns out the issue is that the view is contained in a ScrollView. Removing the ScrollView fixes the problem.


An easy way to solve this is to create a reference to the scroll view e.g. myScrollView = (ScrollView) findViewById(R.id.myScrollView). Then in onTouchEvent, ACTION_DOWN state:

myScrollView.requestDisallowInterceptTouchEvent(true);

And in ACTION_UP

myScrollView.requestDisallowInterceptTouchEvent(false);


At the bottom of your switch, try adding

default:
    break;

Might not be the fix, but it's good practice to have that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜