Android 2指触摸触发1指触摸以及2指触摸

Android 2 finger touch triggering 1 finger touch as well as 2 finger touch

我的应用程序出现问题,我需要根据是按下一根手指还是按下两根手指来执行不同的操作。

目前我有以下代码:

    @Override
    public boolean onTouchEvent(MotionEvent event){
        int touchX = (int)event.getX();
        int touchY = (int)event.getY();
        int action = event.getActionMasked();

        //Multitouch
        if(event.getPointerCount() > 1 && action == MotionEvent.ACTION_POINTER_DOWN){
            System.out.println("2 Finger press");

            return true;
        }
        else if(action == MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_POINTER_DOWN){

            if(event.getPointerCount() == 1) {
                System.out.println("single finger down");
                invalidate();
                return true;
            }
        }

        return false;
    }

我遇到的问题是,当我用 2 个手指按下时,多点触控部分会注册,然后单按也会注册。

我在谷歌上搜索了一些解决方法,这就是为什么我要检查 action != MotionEvent.ACTION_POINTER_DOWN 我认为可以解决问题的单点触摸条件。这并没有解决问题,因此我决定检查 event.getPointerCount() == 1,但不幸的是,当我用 2 个手指按下时,这仍然会导致两行打印。

总而言之,我只需要在按下 2 个手指而不是同时按下时调用 2 手指部分。

参考“Handling Multi-Touch Gestures”的文档。它详细说明了您正在寻找的内容。

本质上,每个活动指针在与屏幕接触时都会分配一个 ID。您的解决方案应该考虑通过观察各种动作状态来发挥作用和删除哪些 ID。

这些方面的一些东西(但要注意兼容性调用 getActionIndex() 之类的方法):

更新的代码示例

public class MotionActivity extends AppCompatActivity {

    private int primaryPointerId   = -1;
    private int secondaryPointerId = -1;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(new FrameLayout(this));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        int action = event.getActionMasked();

        switch(action) {
            case MotionEvent.ACTION_DOWN:
                primaryPointerId = event.getPointerId(0);

                Log.d(getClass().getName(), "Primary pointer ID == [" + primaryPointerId + "]");

                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                secondaryPointerId = event.getPointerId(event.getActionIndex());

                Log.d(getClass().getName(), "Secondary pointer ID == [" + secondaryPointerId + "]");

                break;

            case MotionEvent.ACTION_MOVE:
                if(primaryPointerId > -1 && secondaryPointerId > -1) {
                    Log.d(getClass().getName(), "Two-point touch...");
                } else {
                    Log.d(getClass().getName(), "One-point touch...");
                }

                break;

            case MotionEvent.ACTION_POINTER_UP:
                if(event.getPointerId(event.getActionIndex()) == primaryPointerId) {
                    primaryPointerId = secondaryPointerId;
                }

                secondaryPointerId = -1;

                break;

            case MotionEvent.ACTION_UP:
                primaryPointerId = -1;

                break;
        }

        return true;
    }
}