web-dev-qa-db-ja.com

アクティビティでのマルチタッチを無効または防止する

ユーザーが連続してすばやくタッチしたいアクティビティのビューがいくつかあり、TouchListenerを使用してこれらのタッチをキャプチャし、MotionEvent.ACTION_DOWNを処理します。ただし、ユーザーが両手を使用している場合、ユーザーが前の指を引き上げる前に次のビューが「タッチ」される可能性が非常に高くなります。このシナリオでは、2番目のビューに必要なMotionEvent.ACTION_MOVEではなく、最初のビューにMotionEvent.ACTION_DOWNが発生します。

この動作を回避または防止する方法はありますか? MotionEvent.ACTION_UPを使用して新しいイベントをディスパッチし、イベントリスナーを削除しようとしましたが、どちらも機能していないようです。

33
cachance7

このシナリオを回避する最良の方法は、ViewGroupを使用し、onInterceptTouchEventメソッドを実装して、適切と思われるようにタッチイベントを手動でルーティングすることです。

これはもともとここで答えられました: Android multitouch!誰かハックしますか?

このソリューションを実装するコード(上記の質問に対する回答のコメントセクションにあります)は、次の場所にあります。 http://Pastebin.com/hiE1aTCw

4
cachance7

アプリ全体でシングルタッチを強制するために見つけた最も簡単な方法は、テーマを使用して設定することです。

<style name="MyTheme" parent="@Android:style/Theme.Holo.Light">
    <item name="Android:windowEnableSplitTouch">false</item>
    <item name="Android:splitMotionEvents">false</item>
</style>

マニフェスト:

  <application
        Android:label="@string/app_name"
        Android:theme="@style/MyTheme" >
67
Jeremie

誰かがまだ最善の解決策を探しているなら、次のコードをxmlに入れてください:

Android:splitMotionEvents = false 
19
Oren Zakay

私はそれをこのようにしました:

@Override
public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub

    if(event.getPointerCount() > 1) {
        System.out.println("Multitouch detected!");
        return true;
    }
    else
        return super.onTouchEvent(event);
}

どのビューでもonTouchEventをオーバーライドできると思います。

7
Pijetren

私はカスタムメソッドを使用してこれを解決しました-したくありませんでした。

public static void setViewGroupEnebled(ViewGroup view, boolean enabled)
{
    int childern = view.getChildCount();

    for (int i = 0; i< childern ; i++)
    {
        View child = view.getChildAt(i);
        if (child instanceof ViewGroup)
        {
            setViewGroupEnebled((ViewGroup) child,enabled);
        }
        child.setEnabled(enabled);
    }
    view.setEnabled(enabled);
}
2
user647826

DispatchTouchEventをオーバーライドし、そこですべてのタッチをインターセプトします。すべてのマルチタッチについて、pointercountは複数です。

 if(ev.getPointerCount() > 1)
  {
     Log.d("Multitouch detected!");
     ev.setAction(MotionEvent.ACTION_CANCEL);
  }

これにより、タッチはキャンセルされ、ボタンの押された状態は、何もせずにクリアされます。

int currentapiVersion = Android.os.Build.VERSION.SDK_INT;

            if (currentapiVersion >= Android.os.Build.VERSION_CODES.HONEYCOMB) {

                horizentalLinearGridItem.setMotionEventSplittingEnabled(false);

            }

ここでhorizentalLinearGridItemは、子ビューを挿入するparentLayoutビューです。私のコードでは、そのLinearLayoutです。このLinearLayoutでは、子ビューを追加しました。しかし、2つの子ビューを同時にクリックすると、両方がイベントを取得していました。それをブロックするには、上記のコードを使用しました。

0
Abhijit Kurane

OnTouchEventメソッドにコードを追加するだけで機能します。

boolean action_down_required = false;

@Override
public boolean onTouchEvent(MotionEvent event) {

    int action = event.getAction();

    if(event.getPointerCount() > 1){
        action_down_required = true;
        return true;
    }

    if(action_down_required){
        action = MotionEvent.ACTION_DOWN;
    }

    switch (action) {
        case MotionEvent.ACTION_DOWN:

            // your code goes here...

            action_down_required = false;
            break;

        // Other events...
0
Amol Mejari