Android перестает отправлять события onTouch

У меня есть собственное представление, для которого я хочу обрабатывать события касания. В частности, перетаскивание пальца по представлению должно вызывать прокрутку его содержимого. Для этого я реализовал следующее 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>

person Tim Timmingson    schedule 02.09.2011    source источник
comment
Пожалуйста, покажите нам макет xml.   -  person Lior Ohana    schedule 02.09.2011
comment
Если я правильно понимаю, action_up они палец убирают? Разве вы не хотите break; после этого, чтобы гарантировать, что action_move не сработает после того, как они уберут палец?   -  person yep    schedule 02.09.2011
comment
Да, возможно, но я не слишком заморачиваюсь по этому поводу. Я все равно отредактирую код, чтобы не отвлекать.   -  person Tim Timmingson    schedule 02.09.2011


Ответы (4)


вам нужно написать оператор break в каждом случае. в противном случае выполняется каждый случай.

        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

person Pratik    schedule 02.09.2011
comment
Это не имеет никакого эффекта, но я все равно отредактировал исходный код. - person Tim Timmingson; 02.09.2011
comment
с какой проблемой вы столкнулись, я проверяю вас, слушатель, он отлично работает, дайте мне координаты вниз, движение и время подъема - person Pratik; 02.09.2011
comment
Перетащите немного влево и вправо, а затем двигайтесь вверх. После этого перемещение влево и вправо не будет создавать события (по крайней мере, не на Nexus One или эмуляторе, на котором я это тестирую). - person Tim Timmingson; 02.09.2011

Оказывается, проблема в том, что представление содержится в ScrollView. Удаление ScrollView устраняет проблему.

person Tim Timmingson    schedule 05.09.2011
comment
Правильно, мой пользовательский вид был в виде вертикальной прокрутки, а события onTouch работали горизонтально в пользовательском представлении, но останавливались при перемещении пальца по вертикали. - person Lumis; 01.12.2012

Простой способ решить эту проблему - создать ссылку на представление прокрутки, например. myScrollView = (ScrollView) findViewById(R.id.myScrollView). Затем в onTouchEvent состояние ACTION_DOWN:

myScrollView.requestDisallowInterceptTouchEvent(true);

И в ACTION_UP

myScrollView.requestDisallowInterceptTouchEvent (ложь);

person Lumis    schedule 01.12.2012

В нижней части переключателя попробуйте добавить

default:
    break;

Возможно, это не исправление, но это хорошая практика.

person NujnaH    schedule 02.09.2011
comment
К сожалению, это ничего не исправило. Я обновил код с вашим предложением. - person Tim Timmingson; 02.09.2011