1

最近アプリのクラッシュ レポートを受け取り、スタック トレースを確認したところ、マルチタッチ コントロールに問題があることがわかりました。

何が起こるかは次のようなものです:

4本の指だけの指押しを記録しようとしています。もういや。4 を超えるものはすべて効果的に「無視」したいと考えています。

したがって、私は次のようなことをしています:

@Override
public boolean onTouchEvent(MotionEvent event) {

    pointerCount = event.getPointerCount();

    if (pointerCount <= 4){

    actionMask = event.getActionMasked();
    pointerIndex = event.getActionIndex();      
    pointerID = event.getPointerId(pointerIndex);
    //etc.............

したがって、4 本以上の指が押されている場合、onTouch 内で何も実行していません。

これは正常に動作しているようです。通常、指 5、6 などには「作用」しません。すべて問題ありません。(以下の理由で「一般的に」と言います).....

問題

ただし、6 本の指を下に置いてから持ち上げると、最後に下に置いた指のポインター ID は 5 になります。 action_upまたはaction_pointer_upで何もしていないため、これは実際には問題ではありません。

ただし、 action_pointer_downでは、90% の確率で、置かれた指が 0 から 3 の間の ID しか持たないという予想される動作が得られます。

ただし、画面に 5 本以上の指を置き、画面をすばやく何度もタップすると、最終的には 4 つ以上のaction_pointer_downイベントに ID が割り当てられます (4、5、6、7 を見たことがあります)。したがって、これらの値を xList および yList 配列に配置しようとすると、範囲外の例外でクラッシュします。

action_pointer_down では、指の x と y を作成したいくつかの配列に保存しているため、これは問題です。(後でいくつかのアクションを実行するためにこの情報が必要です) これらの配列のサイズはそれぞれ 4 です (インデックス 0 から 3 になります)。このような:

case MotionEvent.ACTION_POINTER_DOWN:{

    try{                        
            if (isJumpPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
                 //Jump here
            }


            else if (isLeftPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
                 //Move left here
            }

            else if(isRightPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
                //Move right here
            }

                //****These lines randomly fail if the pointerID >=4
                xList[pointerID]=event.getX(pointerIndex);
                yList[pointerID]=event.getY(pointerIndex);

    }
    catch(Exception e){                         
        Log.v("Error","Oops, something's wrong");                   
    }

    break;

    }

}

どうしてこれなの?これはマルチタッチ API のバグですか、それとも私が理解していないものですか。通常の使用では、エラーは通常発生しませんが、自分で簡単にトリガーでき、ユーザーが見つけたので、助けていただければ幸いです。フィンガー ダウン イベントは、0 ~ 3 の ID しか受信しないと予想されます。私が何かを誤解していない限り。

4

1 に答える 1

1

ポインターの ID が連続していることや、現在画面に触れているポインターの数に直接関連していることに依存しないでください。ID は識別子であり、何本の指が押されているか、またはどの指が押されているかを識別する方法ではありません。

ドキュメントには、ID は単に 0 から 0 までの値でgetPointerCount() - 1あり、ID は特定のジェスチャ内で使用されると記載されています。したがって、Android が素早いタップを 1 つのジェスチャとして解釈する場合、同じ指で複数回タップすると、ID が異なる可能性があります。

特定のケースでは、Map<int, float>特定のポインターを X 座標と Y 座標にマッピングする方がうまくいくように思えます。マップを使用すると、範囲外の例外が確実に修正されます。

例えば:

Map<Integer, Float> xMap = new HashMap<>();
// ...

case MotionEvent.ACTION_POINTER_DOWN: 
    // ...

    xMap.put(pointerID, event.getX(pointerIndex);

たとえば、ID 2 のポインターの値を後で取得できますxMap.get(2)

于 2014-12-25T19:19:56.720 に答える