更改长按延迟时间

27

我通过setOnLongClickListener()监听视图的长按事件,我能否更改长按延迟/持续时间?

7个回答

25
这是我设置长按持续时间的方法。
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;
        }
    });

22
据我所知,不行。它是通过ViewConfiguration上的getLongPressTimeout()在框架中硬编码实现的。
您可以处理自己的触摸事件并定义自己的“长按”概念。只要确保它与用户期望的不要有太大差异,大多数用户都希望与其他应用程序使用的标准500ms持续时间相同。

3
如何定义自己的长按概念? - zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
谢谢,我想我现在会坚持使用默认设置。 - fhucho
@zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 可能是通过重写 View 实现的。顺便说一句,很酷的用户名;-) - fhucho

18

我在Kotlin中定义了一个扩展函数,受@Galoway的答案启发:

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
        }
    })
}

使用方法如下:

button.setOnVeryLongClickListener {
    // Do something here
}

运行完美!谢谢! - Bbeni
Krasvcheg,好的解决方案。 - Alexey O.
1
我建议在listener.invoke()之前添加performHapticFeedback(HapticFeedbackConstants.LONG_PRESS),以添加与系统长按事件相同的触觉反馈。 - AndrazP

7
这是我所使用的方法。它与Cumulo Nimbus的答案相似,但有两个显著的区别。
  1. 使用已存储的事件值来获取停机时间和当前时间。这不仅避免了重复工作,还使监听器在不跟踪每个单独事件的开始时间的情况下可用于多个视图。
  2. 检查 view.isPressed 以确保用户在触摸事件期间没有移开视图。这模仿了默认系统行为的 onClickonLongClick

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;
}

如果视图通常不可点击,则需要调用view.setClickable(true)使view.isPressed()检查工作。

简单而优雅! - vss

6
我找到了解决此限制的最简单的工作方法:

这是我发现的最简单的可行解决方案:

//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;
      }
    });

1

这是我为处理同一个按钮的点击和自定义长按所做的内容

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(final View v, final 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);

}

1
这个很好用!为了使v和startTime在run方法中可访问,它们必须被声明为final。私有void initSendInfo(final View v,final long startTime){...} - Lipsyor
编辑:针对initSendInfo方法,按照Lipsyor的建议为参数添加了final关键字。谢谢Lipsyor。 - Sunny Jha

0

这是我在使用 Kotlin 时,在 API 29 上使按钮保持视觉下降状态的方法:

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!")
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接