如何编写多点触控代码

8

我正在开发一个需要处理多点触控的应用程序。基本上,我想要单点触控来实现旋转(这没有问题),而使用多点触控来进行滚动。

我已经编写了基本代码,但是在单点触控和多点触控之间切换时出现了问题。基本上,由于多点触控(两个手指)的中位位置和单个手指的绝对位置之间有一定距离,因此移动会出现抖动。例如,如果我在屏幕上放置了两个手指,它们组成一个中位位置,然后将其中一个手指抬起,就会像从那个中位位置快速移动到单个手指的绝对位置一样。这是我不希望出现的移动。

以下是我的代码:

@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函数只是设置了触摸移动的第一个值。因此,当从多点触控返回时,我还将其用于上升运动,以设置单点触控运动的新起始值。
希望有人知道我的问题并能够帮助我进一步解决。
2个回答

10

如果您还没有阅读过它,请从这里开始,它涉及Android中的多点触控:http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html

关于您发布的代码,有以下几点需要注意:

  1. ACTION_DOWN只会在指针数为1时发生。当第一个手指按下屏幕时,才会发送ACTION_DOWN,所有接下来的手指接触屏幕,都将发送ACTION_POINTER_DOWN
  2. 不要假定只有最多两个手指同时触摸屏幕,可能还有更多。
  3. 使用掩码操作(使用MotionEvent#getActionMasked())比为每个指针索引编写代码要容易得多。
  4. 最终,指针索引只对从MotionEvent中提取数据有用。如果要跟踪时间内的指针移动,请使用指针ID。
  5. 指针ID只是数字,除了它们将是从0开始的整数之外,不要对它们的值做出任何假设。

谢谢!我刚刚完成了一个80%的实现。但是在阅读了那个链接之后,我认为可以使用掩码和ID来做得更好。 - Espen

2
你可以通过简单的数学计算来解决这个问题,尽管可能已经有更好的内置方法了。
只需创建一个对象,用于在ACTION_POINTER_X_UP事件触发时保存每个手指的位置,并创建一个布尔对象,用于保存您上次使用的触摸模式类型。
case MotionEvent.ACTION_POINTER_1_UP:
        camera.onTouchDown( xEvent[ 1 ], yEvent[ 1 ] );
        boolean usedMultiTouch = true;
        int x = event.getX(1);
        int y = event.getY(1);
        return true;

接下来,当用户从多点触控转换为单点触控时,您的ACTION_MOVE(在case=1中)语句将被触发。

现在,根据您想要做什么,您可以忽略单个移动(布尔值是您的检查),直到.ACTION_UP事件触发并将布尔值设置回false

或者

您调用一个方法,该方法基于保存的位置值和仍在屏幕上的手指执行一些数学运算。数学应该很简单,但我不知道您实际想要做什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接