如何编写多点触控代码

发布于 2024-10-03 14:45:49 字数 2120 浏览 4 评论 0原文

所以我正在开发一个必须处理多点触控的应用程序。基本上我想要单点触摸来旋转(这没问题)。以及用于滚动的多点触控。

我已经有了基本代码,但是当从单点触控转变为多点触控(反之亦然)时,我遇到了问题。基本上,移动会震动,因为多点触控(两个手指)的中间位置和单个手指的绝对位置有一定距离。因此,如果我在屏幕上有两根手指,它们构成一个中间位置,然后抬起一根手指,这就像从该中间位置快速移动到绝对单指位置。这将是我不想要的运动。

这是我的代码:

@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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

宫墨修音 2024-10-10 14:45:49

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

关于您发布的代码的一些信息:

  1. 您'永远不会看到指针计数为 2 的 ACTION_DOWNACTION_DOWN 仅针对第一个下降的指针发送。在第一个手指之后触摸屏幕的所有手指都会发送 ACTION_POINTER_DOWN
  2. 不要假设只有最多 2 个手指触摸,很容易有更多。
  3. 使用屏蔽动作(使用 MotionEvent#getActionMasked())比单独为每个指针索引编写代码要容易得多。
  4. 最后,索引仅在从 MotionEvent 中提取数据时起作用。如果您要跟踪指针随时间的移动,请使用指针 ID。
  5. 指针 ID 只是数字。不要假设它们将具有什么值,除非它们是 0 及以上的整数。

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:

  1. You'll never see 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 send ACTION_POINTER_DOWN.
  2. Don't assume only up to 2 finger touch, there can easily be more.
  3. It's a lot easier to work with the masked action (use MotionEvent#getActionMasked()) than to code for each pointer index individually.
  4. In the end, indices only matter for pulling data out of a MotionEvent. If you're tracking pointer movement over time, use the pointer ID.
  5. Pointer IDs are just numbers. Don't make assumptions as to what values they will have other than that they will be integers from 0 and up.
ゝ偶尔ゞ 2024-10-10 14:45:49

您可以通过简单的数学来解决这个问题,尽管可能已经内置了更好的方法。

只需创建一个在 .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

,或者

您调用一个基于保存的位置值和仍在屏幕上的手指。数学应该很简单,但我不知道你到底想做什么。

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.

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;

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文