【问题标题】:Android 2 finger touch triggering 1 finger touch as well as 2 finger touchAndroid 2 指触摸触发 1 指触摸以及 2 指触摸
【发布时间】:2017-06-16 01:19:33
【问题描述】:

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

目前我有以下代码:

    @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 个手指部分。

【问题讨论】:

    标签: java android multi-touch touch-event


    【解决方案1】:

    请参阅有关“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;
        }
    }
    

    【讨论】:

    • 我将不得不重新阅读相关文档并弄清楚如何去做。我相信您的示例代码是错误的,但是,它根本没有记录 2 次手指按压。我认为这是由 secondaryPointerId = -1 引起的,这意味着永远不会满足多点触控条件
    • secondaryPointerId 应在收到MotionEvent.ACTION_POINTER_DOWN 的操作时分配。我关于如何引用正确动作索引的机制可能不正确(我在记忆中写下了),但要点是正确的。如果secondaryPointerId == -1 那是因为表面上有一个(或没有)手指。
    • 我对此进行了更多研究,问题是case MotionEvent.ACTION_POINTER_DOWN 从未真正输入过,我还没有弄清楚原因,但除此之外,我认为这是正确的。我明白你对secondaryPointerId的意思
    • 我的代码示例的问题是我愚蠢地将指针 ID 写成方法范围的变量。相反,它们应该是成员变量。我已经粘贴了一个更新的工作版本。对此感到抱歉!
    • 很高兴为您提供帮助!不过,请务必阅读文档。它解释了有关如何管理指针 ID 的重要框架行为,例如在第一个触摸指针同时也是第一个释放的情况下,等等。
    猜你喜欢
    • 1970-01-01
    • 2017-02-28
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多