Android : How to implement longpress manually in touch event?

前端 未结 4 1965
庸人自扰
庸人自扰 2021-02-11 05:07

Short version: I want a way to start a time-based counter on an onTouchEvent, and test to see if a certain amount of time has passed before responding, as a manual LongTouch det

相关标签:
4条回答
  • 2021-02-11 05:51

    Answer: Use system clock (elapsedRealtime()) and measure milliseconds since the press was initiated. Easy once you start to get the hang of it.

    0 讨论(0)
  • Just look in the source code of android.

    Long press in GestureDetector starts a delayed message on "key down". When this message is coming before "key up" it is an long press.

    Just a link to the source http://www.devdaily.com/java/jwarehouse/android/core/java/android/view/GestureDetector.java.shtml

    0 讨论(0)
  • 2021-02-11 05:53

    I'm not sure from you question, but it seems that you're trying to implement a catch long click event in your onTouchListener except you need to perform some kind of logic before the ACTION_UP event happens? If so, that's the same exact problem I was having. I also tried using System.nanoTime() but I found a less tricky method. You CAN use a timer, you just have to schedule it on the first ACTION_DOWN event and cancel it when anything adverse happens (like an ACTION_UP which means it's wasn't a long press but just a click, or an ACTION_MOVE with a displacement over a certain threshold). Something like the following:

    layout.seyOnTouchListener(new OnTouchListener(){
        private Timer longpressTimer; //won't depend on a motion event to fire
        private final int longpressTimeDownBegin = 500; //0.5 s
        private Point previousPoint;
    
        switch(event.getAction()){
    
        case MotionEvent.ACTION_DOWN:{
            longPressTimer = new Timer();
            longpressTimer.schedule(new TimerTask(){
                //whatever happens on a longpress
            }, longpressTimeDownBegin);
            return true; //the parent was also handling long clicks
        }
        case MotionEvent.ACTION_MOVE:{
            Point currentPoint = new Point((int)event.getX(), (int)event.getY());
    
            if(previousPoint == null){
                previousPoint = currentPoint;
            }
            int dx = Math.abs(currentPoint.x - previousPoint.x);
            int dy = Math.abs(currentPoint.y - previousPoint.y);
            int s = (int) Math.sqrt(dx*dx + dy*dy);
            boolean isActuallyMoving = s >= minDisToMove; //we're moving
    
            if(isActuallyMoving){ //only restart timer over if we're actually moving (threshold needed because everyone's finger shakes a little)
                cancelLongPress();
                return false; //didn't trigger long press (will be treated as scroll)
            }
            else{ //finger shaking a little, so continue to wait for possible long press
                return true; //still waiting for potential long press
            }
        }
        default:{
            cancelLongPress();
            return false;
        }
        }
    }
    
    0 讨论(0)
  • 2021-02-11 05:58

    The way I would approach this would be to set some boolean to true when Action_Down occurs. If action_up occurs then set the boolean to false. Also start a postDelayed set to whatever delay you want when action_down occurs. In the postdelayed, if the boolean that you earlier set to true is still true then do what you want. Sorry for such a wordy answer but that is how I would do it.

    0 讨论(0)
提交回复
热议问题