2

我正在开发一个支持 Talkback 和 Explore By Touch 的 Android 应用程序,但是在使用自定义视图响应两指滚动时遇到了问题。

据我了解,在屏幕上按住两根手指并四处移动它们应该在自定义视图 onTouchEvent 方法中生成相同的触摸事件序列,就像在关闭 Talkback/Explore By Touch 的情况下使用单指一样。

当用户用两根手指触摸屏幕时,我希望看到一个 ACTION_DOWN 事件,然后是一系列 ACTION_MOVE 事件,最后是当他们停止触摸屏幕时的一个 ACTION_UP 事件。

这种情况有时会发生,但经常发生,将两根手指放在屏幕上时,我会收到一连串难以正确解释的事件。

为了尽可能多地减少代码,我编写了一个简单的示例应用程序,它只是一个使用 ADT 向导创建的基本 Android 应用程序,具有如下声明的单个自定义视图;

package com.example.accesseventtest;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class AccessTestView extends View {

    public AccessTestView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        int action_type = event.getActionMasked();

        if (action_type != MotionEvent.ACTION_MOVE)
            Log.d("onTouchEvent", event.toString());

        return true;
    }
}

自定义视图旨在消耗所有通过的触摸事件并返回 true 以指示这一点,它还将所有事件复制到调试日志中,除了 ACTION_MOVE 以减少产生的调试日志量。它由以下布局实例化;

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.accesseventtest.MainActivity" >

    <com.example.accesseventtest.AccessTestView 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
        />
</RelativeLayout>

在启用 Talkback 和 Explore By Touch 的情况下运行此程序,然后将两根手指放在屏幕上,有时会向调试日志发出单个 ACTION_DOWN 事件,如下所示;

10-06 14:21:41.356: D/onTouchEvent(30151): MotionEvent { action=ACTION_DOWN, id[0]=1, x[0]=828.0, y[0]=744.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=23426762, downTime=23426762, deviceId=4, source=0x1002 }

这将是理想的,但是它有时会发出这个序列;

10-06 14:32:53.026: D/onTouchEvent(30151): MotionEvent { action=ACTION_DOWN, id[0]=1, x[0]=926.0, y[0]=607.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0,metaState=0,flags=0x0,edgeFlags=0x0,pointerCount=1,historySize=0,eventTime=24098432,downTime=24098444,deviceId=4,source=0x1002 }

10-06 14:32:53.031: D/onTouchEvent(30151): MotionEvent { action=ACTION_CANCEL, id[0]=1, x[0]=1054.0, y[0]=801.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0,metaState=0,flags=0x0,edgeFlags=0x0,pointerCount=1,historySize=0,eventTime=24098449,downTime=24098444,deviceId=4,source=0x1002 }

10-06 14:32:53.036: D/onTouchEvent(30151): MotionEvent { action=ACTION_DOWN, id[0]=1, x[0]=926.0, y[0]=608.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=24098444, downTime=24098444, deviceId=4, source=0x1002 }

这也不是问题,因为我可以在收到 CANCEL 时过滤掉第一个 DOWN 动作。出现问题的地方是当它发出大量这样的事件时;

10-06 14:20:47.681: D/onTouchEvent(30151): MotionEvent { action=ACTION_DOWN, id[0]=1, x[0]=697.0, y[0]=933.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0,metaState=0,flags=0x0,edgeFlags=0x0,pointerCount=1,historySize=0,eventTime=23373092,downTime=23373092,deviceId=4,source=0x1002 }

10-06 14:20:47.731: D/onTouchEvent(30151): MotionEvent { action=ACTION_UP, id[0]=1, x[0]=697.0, y[0]=936.5, toolType[0]=TOOL_TYPE_FINGER, buttonState=0,metaState=0,flags=0x0,edgeFlags=0x0,pointerCount=1,historySize=0,eventTime=23373137,downTime=23373092,deviceId=4,source=0x1002 }

10-06 14:20:47.731: D/onTouchEvent(30151): MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=954.0, y[0]=643.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=23373137, downTime=23373137, deviceId=4, source=0x1002 }

10-06 14:20:47.736: D/onTouchEvent(30151): MotionEvent { action=ACTION_POINTER_DOWN(1), id[0]=0, x[0]=954.0, y[0]=643.0, toolType[0] =TOOL_TYPE_FINGER, id[1]=1, x[1]=696.0, y[1]=937.0, toolType[1]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2 , historySize=0, eventTime=23373137, downTime=23373137, deviceId=4, source=0x1002 }

最初的 DOWN,UP,DOWN 序列混淆了更高级别的代码并被解释为点击事件。

任何成功实现自定义视图的人都可以通过启用 Talkback/Explore By Touch 实现支持两指滚动的自定义视图,能否说明我在哪里出错了?

4

0 回答 0