我正在开发一款支持Talkback和Touch 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序列会混淆更高级别的代码,并被解释为点击事件。
任何成功实现自定义视图的人都可以通过Touchback / Explore By Touch启用支持两个手指滚动功能,这可以解决我在哪里出错吗?