【问题标题】:multiTouch android | getting Action of each touch point多点触控安卓 |获取每个接触点的动作
【发布时间】:2013-05-13 07:18:08
【问题描述】:

我正在尝试在 android 中处理 multiTouch,我的计划是在应用程序中使用 2 个手指。我知道如何使用一个接触点,但我不确定如何使用多个接触点。

这是我的代码,OnTouch:

    public boolean onTouch(View view, MotionEvent event) {

        for(int i = 0; i < event.getPointerCount(); i++){

            float x = event.getX(i);
            float y = event.getY(i);

           // using the data here...
          //....
       }
    return true;
}

现在,在我获得每个点的 x 和 y 坐标后,我将如何获得发生的动作?我想使用event.getAction,但它不带点索引等参数。如何获取每个接触点的动作类型?

更新: 好的,所以现在我可以成功管理和处理两个手指,现在,在我完成之后,我创建了一个名为 Finger 的简单类来处理每个触摸点,现在每当我有两个手指在屏幕上时,我尝试移除其中一个,然后移动/移除另一根手指,游戏就会崩溃!

触摸屏:

public boolean onTouch(View view, MotionEvent event) {

        int pointerCount = event.getPointerCount();

        if(pointerCount > 2){
            pointerCount = 2;
            System.out.println("too many fingers!");
        } // since i want to handle only two fingers, every other finger will be ignored.

        for (int i = 0; i < pointerCount; i++) {

            float x = event.getX(i);
            float y = event.getY(i);

            int id = event.getPointerId(i);
            int action = event.getActionMasked();
            int actionIndex = event.getActionIndex();

            if (action == MotionEvent.ACTION_DOWN
                    || action == MotionEvent.ACTION_POINTER_DOWN) {

                if (fingers.get(i) == null)
                    fingers.set(i, new Finger(x, y, id));


            }

            if (fingers.get(i).type == Finger.SCREEN_FINGER) {

                switch (action) {
                case MotionEvent.ACTION_UP:
                    fingers.set(i, null);
                    System.out.println(id + " action_up!");
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    fingers.set(i, null);
                    System.out.println(id + " pointer_up!");
                    break;
                case MotionEvent.ACTION_MOVE:
                    fingers.get(i).setPos(x, y);
                    System.out.println(id + " action_move!, x: "+fingers.get(i).x+", y: "+fingers.get(i).y);
                    break;
                default:

                }
            }else if (fingers.get(i).type == Finger.DPAD_FINGER) {
                switch (action) {
                case MotionEvent.ACTION_UP:
                    fingers.set(i, null);
                    System.out.println(id + " action_up! - dpad");
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    fingers.set(i, null);
                    System.out.println(id + " pointer_up! - dpad");
                    break;
                case MotionEvent.ACTION_MOVE:
                    fingers.get(i).setPos(x, y);
                    System.out.println(id + " action_move! - dpad, x: "+fingers.get(i).x+", y: "+fingers.get(i).y);
                    break;
                default:

                }
            }
        }


        return true;
    }

我为手指创建一个列表:

列出手指 = new LinkedList();

在我放入的构造函数中:

fingers.add(0, null);
fingers.add(1, null);

最后是手指类:

public class Finger {
public final static int DPAD_FINGER = 0;
public final static int SCREEN_FINGER = 1;

public float x, y;
public int type;
public int id;

public Finger(float x, float y,int id) {
    this.id = id;
    checkType(x, y);
}

public void checkType(float x, float y) {
    if(x>Dpad.x && x < Dpad.x+Dpad.Width && y> Dpad.y && y<Dpad.y+Dpad.Height){
        System.out.println("inside DPAD");
        type = DPAD_FINGER;
    }else{
        System.out.println("Outside DPAD");
        type = SCREEN_FINGER;
    }

}

public void setPos(float x, float y){
    this.x = x;
    this.y = y;
}



}

现在,当我执行所有这些操作时,一切都很好,直到我移开一根手指并移动/移开另一根手指,我在 LogCat 中收到以下错误:

 05-18 15:22:03.812: E/InputEventReceiver(20124): Exception dispatching input event.
05-18 15:22:03.812: W/dalvikvm(20124): threadid=1: thread exiting with uncaught exception (group=0x41e00438)
05-18 15:22:03.822: E/AndroidRuntime(20124): FATAL EXCEPTION: main
05-18 15:22:03.822: E/AndroidRuntime(20124): java.lang.NullPointerException
05-18 15:22:03.822: E/AndroidRuntime(20124):    at smellychiz.projects.ogc.util.ChizView$1.onTouch(ChizView.java:70)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.View.dispatchTouchEvent(View.java:7241)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at    com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2116)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1469)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.app.Activity.dispatchTouchEvent(Activity.java:2477)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2064)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.View.dispatchPointerEvent(View.java:7430)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3457)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3389)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4483)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4461)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4565)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:163)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4533)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4584)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.Choreographer.doFrame(Choreographer.java:523)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.os.Handler.handleCallback(Handler.java:615)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.os.Handler.dispatchMessage(Handler.java:92)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.os.Looper.loop(Looper.java:137)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at android.app.ActivityThread.main(ActivityThread.java:4950)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at java.lang.reflect.Method.invokeNative(Native Method)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at java.lang.reflect.Method.invoke(Method.java:511)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
05-18 15:22:03.822: E/AndroidRuntime(20124):    at dalvik.system.NativeStart.main(Native Method)

更新:

我没有重新设置手指并将它们设置为空然后再次重新设置它们,而是在手指向上时将它们移除,并在手指向下时重新创建它们并在手指移动时更新它们。现在它工作得很好!

更新....

最终问题没有解决,即使应用程序没有崩溃,当一个手指被抬起时,它的行为就像两个手指都被抬起一样。

这是onTouch方法的当前代码:

public boolean onTouch(View view, MotionEvent event) {

    int pointerCount = event.getPointerCount();

    if(pointerCount > 2){
        pointerCount = 2;
        System.out.println("too many fingers!");
    } // since i want to handle only two fingers, every other finger will be ignored.

    for (int i = 0; i < pointerCount; i++) {

        float x = event.getX(i);
        float y = event.getY(i);

        int id = event.getPointerId(i);
        int action = event.getActionMasked();
        int actionIndex = event.getActionIndex();

        if (action == MotionEvent.ACTION_DOWN
                || action == MotionEvent.ACTION_POINTER_DOWN) {

            if (fingers.get(i) == null)
                fingers.add(i, new Finger(x, y, id));


        }

        if (fingers.get(i).type == Finger.SCREEN_FINGER) {

            switch (action) {
            case MotionEvent.ACTION_UP:
                fingers.remove(i);
                System.out.println(id + " action_up!");
                break;
            case MotionEvent.ACTION_POINTER_UP:
                fingers.remove(i);
                System.out.println(id + " pointer_up!");
                break;
            case MotionEvent.ACTION_MOVE:
                fingers.get(i).setPos(x, y);
                System.out.println(id + " action_move!, x: "+fingers.get(i).x+", y: "+fingers.get(i).y);
                break;
            default:

            }
        }else if (fingers.get(i).type == Finger.DPAD_FINGER) {
            switch (action) {
            case MotionEvent.ACTION_UP:
                fingers.remove(i);
                System.out.println(id + " action_up! - dpad");
                break;
            case MotionEvent.ACTION_POINTER_UP:
                fingers.remove(i);
                System.out.println(id + " pointer_up! - dpad");
                break;
            case MotionEvent.ACTION_MOVE:
                fingers.get(i).setPos(x, y);
                System.out.println(id + " action_move! - dpad, x: "+fingers.get(i).x+", y: "+fingers.get(i).y);
                break;
            default:

            }
        }
    }

因此,只要一根手指抬起,logCat 就会像两根手指都从屏幕上抬起一样写入。有任何想法吗?

【问题讨论】:

    标签: android multi-touch touch-event ontouchlistener touchscreen


    【解决方案1】:

    【讨论】:

    • 好的,所以我可以成功处理两个触摸点,所以我创建了一个名为Finger 的简单类来处理每个带有 id 的触摸点并跟踪 x 和 y 坐标。现在,我有一个问题,当我在屏幕上有两根手指时,我尝试移除其中一个,然后我移动/移除另一根手指,应用程序就会崩溃!我将在问题中发布我的代码。
    • 请查看最近的更新。我将不胜感激任何帮助。谢谢。
    • 没有错误,我认为这只是我处理方法的方式,当一个手指向上时,它报告好像两个手指都向上
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多