LongClick event happens too quickly. How can I increase the clicktime required to trigger it?

后端 未结 8 1503
暖寄归人
暖寄归人 2020-12-08 21:26

In an application I\'m working on, I have the requirement that a user must click & hold a component for a period time before a certain action occurs.

I\'m curren

8条回答
  •  伪装坚强ぢ
    2020-12-08 22:12

    I worked out a solution with the help of Rohan :)
    I adapted his answer to fit my requirements.

    When the user pushes the button, a thread is started. The thread sleeps for my desired delay, then when it wakes up, it executes whatever code I need it to do. When the user lets go, the thread is killed. This accomplishes what I want, because if the user lets go before the thread wakes up, the thread is interrupted and the action doesn't occur.

    I like this approach because it lets me execute my business logic as soon as the delay is up, which is good because I can give the user some feedback letting them know they've pushed long enough (the phone can vibrate, for example).
    The downside to this approach is: there is a risk that the user lets go of the button while your desired action is running, and kills the thread before everything is done. This isn't a huge problem for my case, because my business logic does very little; it just fires an event for some other class to process. If the action didn't complete fully, it's acceptable for the user to have to try again.

    The code is a little longer than I'd like, but if this is a common feature in your application, it's easily re-useable. Here's a code example:

    protected class MyLongClickListener implements View.OnTouchListener {
        private Thread longClickSensor;
    
        public boolean onTouch(View view, MotionEvent event) {
            // If the user is pressing down and there is no thread, make one and start it
            if (event.getAction() == MotionEvent.ACTION_DOWN && longClickSensor == null) {
                longClickSensor = new Thread(new MyDelayedAction());
                longClickSensor.start();
            }
            // If the user has let go and there was a thread, stop it and forget about the thread
            if (event.getAction() == MotionEvent.ACTION_UP && longClickSensor != null) {
                longClickSensor.interrupt();
                longClickSensor = null;
            }
            return false;
        }
    
        private class MyDelayedAction implements Runnable {
            private final long delayMs = 1200;
    
            public void run() {
                try {
                    Thread.sleep(delayMs); // Sleep for a while
                    doBusinessLogic();     // If the thread is still around after the sleep, do the work
                } catch (InterruptedException e) { return; }
            }
            private void doBusinessLogic() {
                // Make sure this logic is as quick as possible, or delegate it to some other class
                // through Broadcasted Intents, because if the user lets go while the work is happenening,
                // the thread will be interrupted.
            }
        }
    }
    

提交回复
热议问题