【问题标题】:Change long click delay更改长点击延迟
【发布时间】:2012-03-31 18:14:57
【问题描述】:

我正在通过 setOnLongClickListener() 监听视图的长按事件。我可以更改长点击延迟/持续时间吗?

【问题讨论】:

    标签: android view


    【解决方案1】:

    这是我设置持续时间长按的方式

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

    【讨论】:

      【解决方案2】:

      AFAIK,不。它通过getLongPressTimeout()ViewConfiguration 在框架中硬连线。

      欢迎您处理自己的触摸事件并定义自己的“长按”概念。只需确保它与用户的期望没有太大的不同,并且用户很可能会期望所有其他应用使用什么,即标准的 500 毫秒持续时间。

      【讨论】:

      • 您将如何定义自己的长点击概念?
      • 谢谢,我想我现在会坚持使用默认设置。
      • @zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 可能是通过覆盖视图。酷用户名顺便说一句;-)
      【解决方案3】:

      我在 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
      }
      

      【讨论】:

      • 完美运行!谢谢!
      • Krasvcheg,horoshee reshenie。
      • 我建议您在 listener.invoke() 之前添加 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) 以添加与系统长按事件相同的触觉反馈。
      【解决方案4】:

      这是我使用的。它类似于 Cumolo 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() 检查生效。

      【讨论】:

      • 简洁优雅!
      【解决方案5】:

      这是我发现的最简单的解决这个限制的方法:

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

      【讨论】:

        【解决方案6】:

        这就是我在处理 onclick 和自定义长按同一个按钮时所做的

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

        【讨论】:

        • 这很好用!要使 run 方法中的 v 和 startTime 可以访问,它们必须声明为 final private void initSendInfo(final View v, final long startTime) { ... }
        • 编辑:对于 initSendInfo 方法,根据 Lipsyor 的 cmets,为参数添加了 final 关键字。 Thanyou Lipsyor。
        【解决方案7】:

        这对我在API 29 有效,同时使用 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!")
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-07
          • 2021-09-16
          • 2021-05-22
          相关资源
          最近更新 更多