android - Android:使用 2 个多点触控点绘制矩形时出现异常行为
问题描述
在完成了一些关于触摸事件的教程并在画布上绘图后,我尝试结合所学知识并制作一个使用 2 个触摸点创建矩形的应用程序。我可以使用单个触摸点拖动并创建一个矩形,但是一旦我使用第二根手指,矩形就会开始表现得很奇怪,要么根本不绘制矩形,要么在拖动一点后消失。此外,例如,如果我通过使一个触摸点位于屏幕的左下角而另一个触摸点位于屏幕的右上角来绘制一个矩形,那么如果我将手指拖动到它们相互交叉的点,该矩形就会消失。
private float xDown = 0,yDown = 0, xUp = 0, yUp = 0;
boolean touched = false;
@Override
protected void onDraw (Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
if(touched) {
canvas.drawRect(xDown, yDown, xUp, yUp, mPaint);
}
}
@Override
public boolean onTouchEvent (MotionEvent event) {
int fingers = event.getPointerCount();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if (fingers == 1) {
xDown = event.getX(0);
yDown = event.getY(0);
xUp = 0;
yUp = 0;
}
if (fingers == 2) {
xUp = event.getX(1);
yUp = event.getY(1);
xDown = event.getX(0);
yDown = event.getY(0);
touched = true;
}
break;
case MotionEvent.ACTION_MOVE:
if (fingers == 1) {
xUp = event.getX();
yUp = event.getY();
touched = true;
}
if (fingers == 2) {
xUp = event.getX(1);
yUp = event.getY(1);
xDown = event.getX(0);
yDown = event.getY(0);
touched = true;
}
break;
case MotionEvent.ACTION_UP:
if (fingers == 1) {
xUp = event.getX();
yUp = event.getY();
touched = true;
}
if (fingers == 2) {
xUp = event.getX(1);
yUp = event.getY(1);
xDown = event.getX(0);
yDown = event.getY(0);
touched = true;
}
break;
}
invalidate();
return true;
解决方案
MotionEvent.ACTION_DOWN 只会在第一次触摸屏幕事件时发生。
“ACTION_DOWN
getActionMasked() 的常量:按下的手势已经开始......”(来自https://developer.android.com/reference/android/view/MotionEvent#ACTION_DOWN)
对于您的SECOND 或更多手指,您需要检查ACTION_POINTER_DOWN
“ACTION_POINTER_DOWN
getActionMasked() 的常量:非主指针已下降...”(来自https://developer.android.com/reference/android/view/MotionEvent#ACTION_POINTER_DOWN)
因为您只使用两个手指,所以您无需担心 ActionIndex ( getActionIndex() )。触摸屏幕的第一根手指始终是ACTION_DOWN,之后的每次触摸都是ACTION_POINTER_DOWN。
在 ACTION_UP 上则相反。每次触摸(最后一次触摸除外)都是 ACTION_POINTER_UP,最后一次触摸是 ACTION_UP。
注意:第一次触摸 (ACTION_DOWN) 的索引始终为 0。索引一直分配给触摸,直到触摸从屏幕上移除。因为您正在对索引进行硬编码,所以对屏幕的任何意外触摸都会导致一些意外结果。对于测试程序,这很好,但您最终需要处理索引。
例子:
手指 1 (ACTION_DOWN) 触摸屏幕,索引为 0。
手指 2 (ACTION_POINTER_DOWN) 触摸屏幕,索引为 1。
手指 3 (ACTION_POINTER_DOWN) 触摸屏幕,索引为 2手指 2(索引 1)从屏幕上抬起 (ACTION_POINTER_UP)
手指 1(索引 0)和手指 3(索引 2)仍在 MotionEvent 中,它们的索引仍然分配给它们。
最简单的更改是更改:
case MotionEvent.ACTION_DOWN:
if (fingers == 1) {
...
至:
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
if (fingers == 1) {
...
也改变:
case MotionEvent.ACTION_UP:
if (fingers == 1) {
...
至:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (fingers == 1) {
...
因为您已经在处理手指计数和索引。
此更改将使您的代码“更正确”,因为它会捕获第二个 DOWN 和第一个 UP,但它不会解决您的问题。ACTION_MOVE 已经在它们移动时捕获了两个接触点,并且您已经在处理两个索引并分配 X 和 Y。所以问题必须在你程序的其他地方。
推荐阅读
- jquery - div中的Jquery日历,单击时添加日期以输入
- html - 漏洞?Mac 上的 Chrome 忽略提交按钮的字体大小
- mysql - SQL:从给定的纬度和经度查找不同半径内的最近点
- node.js - nodejs 重用同一服务器的最后一个 TLS 连接
- ms-access - 如何通过 ODBC 将表与 VBA 代码链接
- angular - 类型“LocationComponent”是 2 个模块声明的一部分:Angular 6?
- javascript - 获取数据并将结果返回给动态创建的元素
- html - 无论内部元素如何,固定 div 的高度
- wordpress - 保存功能上的wordpress古腾堡验证错误
- python - Django 2.1 - 'functools.partial' 对象没有属性 '__name__'