AnswerBun.com

Change long click delay

I am listening for a View’s long click events via setOnLongClickListener(). Can I change the long click delay / duration?

Stack Overflow Asked by fhucho on January 1, 2021

7 Answers

7 Answers

AFAIK, no. It is hard-wired in the framework via getLongPressTimeout() on ViewConfiguration.

You are welcome to handle your own touch events and define your own "long click" concept. Just be sure that it is not too dramatically different from what the user expects, and most likely the user will expect what all the other apps use, which is the standard 500ms duration.

Correct answer by CommonsWare on January 1, 2021

This is what worked for me on API 29, while retaining the button's visual down state using Kotlin:

fun AppCompatButton.setOnVeryLongClickListener(
  holdDuration: Long = 1000L, 
  listener: () -> Unit
) {
    val handler = Handler()
    val originalText = this.text

    setOnTouchListener { v, event ->
        if (event?.action == MotionEvent.ACTION_DOWN) {
            // update the copy of the button
            text = "$originalText (KEEP HOLDING)"

            // fire the listener after our hold duration
            handler.postDelayed({ listener.invoke() }, holdDuration)
        } else if(event?.action == MotionEvent.ACTION_UP) {
            // update the copy of the button
            text = "$originalText (TAP & HOLD)"

            // in case of an interruption, cancel everything
            handler.removeCallbacksAndMessages(null)
        }

        // return false in order to retain the button's visual down state
        false
    }
}

button.setOnVeryLongClickListener {
    println("very long!")
}

Answered by KBog on January 1, 2021

This is what I did for handeling both onclick and custom long click on same button

public static final int LONG_PRESS_DELAY_MILLIS = 3000;

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn_save:
            saveInfo();
            break;

        default:
            break;
    }
}

@Override
public boolean onLongClick(View v) {
    switch (v.getId()) {
        case R.id.btn_save:
            initSendInfo(v, System.currentTimeMillis());
            return true;

        default:
            return false;
    }
}

private void initSendInfo(View v, long startTime) {
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            if (v.isPressed() && System.currentTimeMillis() - startTime >= LONG_PRESS_DELAY_MILLIS) {
                sendInfo();
                return;
            } else if (!v.isPressed()) {
                return;
            }
        }
    }, LONG_PRESS_DELAY_MILLIS);

}

Answered by Sunny Jha on January 1, 2021

I defined an extension function in Kotlin inspired by @Galoway answer:

fun View.setOnVeryLongClickListener(listener: () -> Unit) {
    setOnTouchListener(object : View.OnTouchListener {

        private val longClickDuration = 2000L
        private val handler = Handler()

        override fun onTouch(v: View?, event: MotionEvent?): Boolean {
            if (event?.action == MotionEvent.ACTION_DOWN) {
                handler.postDelayed({ listener.invoke() }, longClickDuration)
            } else if (event?.action == MotionEvent.ACTION_UP) {
                handler.removeCallbacksAndMessages(null)
            }
            return true
        }
    })
}

Use it like this:

button.setOnVeryLongClickListener {
    // Do something here
}

Answered by vovahost on January 1, 2021

This is what I use. It is similar to Cumulo Nimbus' answer, with two notable differences.

  1. Use the already stored event values for down time and current time. Aside from not duplicating effort, this has the nice effect of making the listener usable for multiple views at the same time without tracking start times for each individual event.
  2. Check view.isPressed to ensure the user has not moved away from the view during the touch event. This mimics the default system behavior for onClick and onLongClick.

long longPressTimeout = 2000;

@Override
public boolean onTouch(View view, MotionEvent event) {
    if (view.isPressed() && event.getAction() == MotionEvent.ACTION_UP) {
        long eventDuration = event.getEventTime() - event.getDownTime();
        if (eventDuration > longPressTimeout) {
            onLongClick(view);
        } else {
            onClick(view);
        }
    }
    return false;
}

If the view is not normally clickable you will need to call view.setClickable(true) for the view.isPressed() check to work.

Answered by mpkuth on January 1, 2021

This is my way for set duration to long press

private int longClickDuration = 3000;
private boolean isLongPress = false;

numEquipeCheat.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                isLongPress = true;
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (isLongPress) {
                            Vibrator vibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
                            vibrator.vibrate(100);
                            // set your code here
                            // Don't forgot to add <uses-permission android:name="android.permission.VIBRATE" /> to vibrate.
                        }
                    }
                }, longClickDuration);
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                isLongPress = false;
            }
            return true;
        }
    });

Answered by Galoway on January 1, 2021

This was the simplest working solution I found to this restriction:

//Define these variables at the beginning of your Activity or Fragment:
private long then;
private int longClickDuration = 5000; //for long click to trigger after 5 seconds

...

//This can be a Button, TextView, LinearLayout, etc. if desired
ImageView imageView = (ImageView) findViewById(R.id.desired_longclick_view);
imageView.setOnTouchListener(new OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
          then = (long) System.currentTimeMillis();
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
          if ((System.currentTimeMillis() - then) > longClickDuration) {
            /* Implement long click behavior here */
            System.out.println("Long Click has happened!");
            return false;
          } else {
            /* Implement short click behavior here or do nothing */
            System.out.println("Short Click has happened...");
            return false;
          }
        }
        return true;
      }
    });

Answered by Cumulo Nimbus on January 1, 2021

Add your own answers!

Related Questions

Truncated backpropagation in PyTorch (code check)

1  Asked on December 7, 2021 by rampatowl

   

Blurred places in TextField

1  Asked on December 7, 2021

   

Masonry style menu columns in mega-menu

2  Asked on December 7, 2021 by joe-rr

     

How to call useState from another Page?

3  Asked on December 7, 2021 by grizzly-bear

       

Get Base64 encode file-data from Input Form

7  Asked on December 7, 2021 by jordan-baucke

       

Restart TeamCity server via web interface

2  Asked on December 7, 2021 by krlmlr

   

SliverOverlapAbsorber being able to accept multiple slivers

1  Asked on December 7, 2021 by basic-coder

 

Pandas plot – Range

1  Asked on December 7, 2021 by user13770492

   

Alternate row colours from 2nd row of the table using CSS

5  Asked on December 7, 2021 by raj-kumar-boddu

       

MsSql Grammar quoteString don’t auto add ‘N’

0  Asked on December 7, 2021 by jay-chu

     

Why loading a library dynamically makes my app crash?

0  Asked on December 7, 2021 by jpo38

     

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved.