如何编写多点触控代码
所以我正在开发一个必须处理多点触控的应用程序。基本上我想要单点触摸来旋转(这没问题)。以及用于滚动的多点触控。
我已经有了基本代码,但是当从单点触控转变为多点触控(反之亦然)时,我遇到了问题。基本上,移动会震动,因为多点触控(两个手指)的中间位置和单个手指的绝对位置有一定距离。因此,如果我在屏幕上有两根手指,它们构成一个中间位置,然后抬起一根手指,这就像从该中间位置快速移动到绝对单指位置。这将是我不想要的运动。
这是我的代码:
@Override
public boolean onTouchEvent( MotionEvent event ) {
float xEvent[] = new float[ 2 ];
float yEvent[] = new float[ 2 ];
switch( event.getPointerCount() ) {
case 1:
xEvent[ 0 ] = event.getX( 0 );
yEvent[ 0 ] = event.getY( 0 );
switch( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
camera.onTouchDown( xEvent[ 0 ], yEvent[ 0 ] );
return true;
case MotionEvent.ACTION_MOVE:
camera.onTouchRotate( xEvent[ 0 ], yEvent[ 0 ] );
return true;
default: return super.onTouchEvent( event );
}
case 2:
xEvent[ 0 ] = event.getX( 0 );
yEvent[ 0 ] = event.getY( 0 );
xEvent[ 1 ] = event.getX( 1 );
yEvent[ 1 ] = event.getY( 1 );
switch( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
camera.onTouchDown( ( ( xEvent[ 0 ] + xEvent[ 1 ] ) / 2 ), ( ( yEvent[ 0 ] + yEvent[ 1 ] ) / 2 ) );
return true;
case MotionEvent.ACTION_MOVE:
camera.onTouchSlide( ( ( xEvent[ 0 ] + xEvent[ 1 ] ) / 2 ), ( ( yEvent[ 0 ] + yEvent[ 1 ] ) / 2 ) );
return true;
case MotionEvent.ACTION_POINTER_1_UP:
camera.onTouchDown( xEvent[ 1 ], yEvent[ 1 ] );
return true;
case MotionEvent.ACTION_POINTER_2_UP:
camera.onTouchDown( xEvent[ 0 ], yEvent[ 0 ] );
return true;
default: return super.onTouchEvent( event );
}
default: return false;
}
}
相机的 onTouchDown 函数只是设置触摸移动的第一个值。这就是为什么我还在向上移动中使用它来为多点触摸时的单点触摸移动设置新的开始值。
我希望有人知道我的问题是什么并可以进一步帮助我。
So I'm developing an application that must handle multitouch. Basically I want single touch for rotating ( this is no problem ). And multitouch for scrolling.
I have the basic code in, but I'm having problems when the shift from single to multitouch, and vice verca, occur. Basically the movement will jolt because the median position of the multitouch ( two fingers ) and the absolute position of the single finger are at a distance. So if I have two fingers on the screen, they make up a median position, and then lift one finger, it would be like a quick movement from that median position to the absolute single finger position. This will be the movement that I don't want.
This is my code:
@Override
public boolean onTouchEvent( MotionEvent event ) {
float xEvent[] = new float[ 2 ];
float yEvent[] = new float[ 2 ];
switch( event.getPointerCount() ) {
case 1:
xEvent[ 0 ] = event.getX( 0 );
yEvent[ 0 ] = event.getY( 0 );
switch( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
camera.onTouchDown( xEvent[ 0 ], yEvent[ 0 ] );
return true;
case MotionEvent.ACTION_MOVE:
camera.onTouchRotate( xEvent[ 0 ], yEvent[ 0 ] );
return true;
default: return super.onTouchEvent( event );
}
case 2:
xEvent[ 0 ] = event.getX( 0 );
yEvent[ 0 ] = event.getY( 0 );
xEvent[ 1 ] = event.getX( 1 );
yEvent[ 1 ] = event.getY( 1 );
switch( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
camera.onTouchDown( ( ( xEvent[ 0 ] + xEvent[ 1 ] ) / 2 ), ( ( yEvent[ 0 ] + yEvent[ 1 ] ) / 2 ) );
return true;
case MotionEvent.ACTION_MOVE:
camera.onTouchSlide( ( ( xEvent[ 0 ] + xEvent[ 1 ] ) / 2 ), ( ( yEvent[ 0 ] + yEvent[ 1 ] ) / 2 ) );
return true;
case MotionEvent.ACTION_POINTER_1_UP:
camera.onTouchDown( xEvent[ 1 ], yEvent[ 1 ] );
return true;
case MotionEvent.ACTION_POINTER_2_UP:
camera.onTouchDown( xEvent[ 0 ], yEvent[ 0 ] );
return true;
default: return super.onTouchEvent( event );
}
default: return false;
}
}
The onTouchDown function of the camera just sets the first value of the touch move. That's why I also use it in the up movement to set a new begin value for the single touch movement when coming from a multitouch.
I hope someone knows what my problem is and can help me further.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您还没有阅读过,请从这里开始,它介绍了 Android 中处理多点触控的许多内容:http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
关于您发布的代码的一些信息:
ACTION_DOWN
。ACTION_DOWN
仅针对第一个下降的指针发送。在第一个手指之后触摸屏幕的所有手指都会发送ACTION_POINTER_DOWN
。MotionEvent#getActionMasked()
)比单独为每个指针索引编写代码要容易得多。MotionEvent
中提取数据时起作用。如果您要跟踪指针随时间的移动,请使用指针 ID。Start here if you haven't read it already, it goes over a number of things dealing with multitouch in Android: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
A few things about your posted code:
ACTION_DOWN
with a pointer count of 2.ACTION_DOWN
is only sent for the first pointer that goes down. All fingers that touch the screen after the first will sendACTION_POINTER_DOWN
.MotionEvent#getActionMasked()
) than to code for each pointer index individually.MotionEvent
. If you're tracking pointer movement over time, use the pointer ID.您可以通过简单的数学来解决这个问题,尽管可能已经内置了更好的方法。
只需创建一个在 .ACTION_POINTER_X_UP 事件触发时保存每个手指位置的对象,以及一个保存您上次使用的触摸模式类型的布尔对象。
接下来,当用户从多点触摸变为单点触摸时移动手指时,您的 ACTION_MOVE (在 case=1 内)语句将触发。
现在,根据您想要执行的操作,您可以忽略单个移动(布尔值是您的检查),直到 .ACTION_UP 事件触发并将布尔值设置回 false
,或者
您调用一个基于保存的位置值和仍在屏幕上的手指。数学应该很简单,但我不知道你到底想做什么。
You can solve this with simple math, although there may be a better way already built in.
Just create an object that holds the position of each finger when the .ACTION_POINTER_X_UP event fires and a boolean object that holds which type of touchmode you last used.
Next your ACTION_MOVE (inside the case=1) statement will fire as the user moves their finger as they went from multi to single touch.
Now, depending on what you want to do, you can either ignore the single move (the boolean is your check) until the .ACTION_UP event fires and you set the boolean back to false
or
you call a method that does some math based on the saved location values and the finger that is still on the screen. The math should be pretty easy, but I don't know what you actually want to do.