【问题标题】:How to prevent rapid double click on a button如何防止快速双击按钮
【发布时间】:2015-09-28 09:18:52
【问题描述】:

我在这里查看了答案 - Android Preventing Double Click On A Button 并像这样实现了 qezt 的解决方案,我已经尝试过 setEnabled(false) 像这样 -

doneButton.setOnClickListener(new View.OnClickListener() {
    @Override
        public void onClick(View v) {

            // mis-clicking prevention, using threshold of 1 second
            if (SystemClock.elapsedRealtime() - doneButtonClickTime < 1000){
                return;
            }

            //store time of button click
            doneButtonClickTime = SystemClock.elapsedRealtime();

            doneButton.setEnabled(false);

            //do actual work 

        }
    });

这些都不适用于超快速双击。

注意 - 处理完成后,我没有设置 doneButton.setEnabled(true)。我只是完成()该活动,因此不会出现按钮过早启用的问题。

【问题讨论】:

  • 为什么setEnabled(false) 没有工作?
  • 你在哪里应用 setEnabled(false);?
  • 你可以在onclick事件中给它
  • @Blackbelt this comment 似乎回答了原因。
  • @Blackbelt 它不起作用。请参阅我在第一条评论中链接到的评论。

标签: android


【解决方案1】:

我就是这样做的,效果很好。

public abstract class OnOneOffClickListener implements View.OnClickListener {

   private static final long MIN_CLICK_INTERVAL=600;

   private long mLastClickTime;

   public static boolean isViewClicked = false;


   public abstract void onSingleClick(View v);

   @Override
   public final void onClick(View v) {
       long currentClickTime=SystemClock.uptimeMillis();
       long elapsedTime=currentClickTime-mLastClickTime;

       mLastClickTime=currentClickTime;

       if(elapsedTime<=MIN_CLICK_INTERVAL)
           return;
       if(!isViewClicked){
           isViewClicked = true;
           startTimer();
       } else {
           return;
       }
       onSingleClick(v);        
   }
    /**
     * This method delays simultaneous touch events of multiple views.
     */
    private void startTimer() {
        Handler handler = new Handler();

        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                    isViewClicked = false;
            }
        }, 600);

    }

}

【讨论】:

    【解决方案2】:

    我在按钮的监听器中使用了这样的函数:

    public static long lastClickTime = 0;
    public static final long DOUBLE_CLICK_TIME_DELTA = 500;
    
    public static boolean isDoubleClick(){
        long clickTime = System.currentTimeMillis();
        if(clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){
            lastClickTime = clickTime;
            return true;
        }
        lastClickTime = clickTime;
        return false;
    }
    

    【讨论】:

    • 这在反转返回布尔值后对我有用。我已经编辑了答案。
    【解决方案3】:

    可能不是最有效的,但最小的逆向:

    ...
    onClick(View v) {
        MultiClickPreventer.preventMultiClick(v);
        //your op here
    }
    ...
    public class MultiClickPreventer {
        private static final long DELAY_IN_MS = 500;
    
        public static void preventMultiClick(final View view) {
            if (!view.isClickable()) {
                return;
            }
            view.setClickable(false);
            view.postDelayed(new Runnable() {
                @Override
                public void run() {
                    view.setClickable(true);
                }
            }, DELAY_IN_MS);
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用此方法。通过使用后期延迟,您可以处理双击事件。

      void debounceEffectForClick(查看视图) {

      view.setClickable(false);
      
      view.postDelayed(new Runnable() {
          @Override
          public void run() {
              view.setClickable(true);
      
          }
      }, 500);
      

      }

      【讨论】:

        【解决方案5】:

        将清单中activity的launchMode设置为singleTop

         <activity
                android:name="com.example.MainActivity"
                android:screenOrientation="portrait"
                android:launchMode="singleTop"/>
        

        【讨论】:

          【解决方案6】:

          Suru 的回答对我很有效,谢谢!

          我想为使用 https://github.com/balysv/material-ripple/blob/master/library/src/main/java/com/balysv/materialripple/MaterialRippleLayout.java 并面临此问题的任何人添加以下答案 -

          app:mrl_rippleDelayClick 默认为真。 这意味着,onClick 只有在显示完波纹后才会执行。因此setEnabled(false)inside onClick 将在延迟后执行,因为涟漪没有完成执行,在此期间您可以双击视图。

          设置app:mrl_rippleDelayClick="false" 来解决这个问题。这意味着一旦单击视图就会调用 onClick,而不是等待波纹完成显示。

          【讨论】:

          • 更多的是评论而不是答案
          • 发布答案比发表评论更好。因为我对 MaterialRippleLayout 也有同样的问题,我为此找到了单独的解决方案。谢谢@Mallika。
          【解决方案7】:
          private static final long MIN_CLICK_INTERVAL = 1000;
          
          private boolean isViewClicked = false;
          
          private View.OnClickListener onClickListener = new View.OnClickListener() {
          @Override
          final public void onClick(View view) {
              if (isViewClicked) {
                return:
              }
              // place your onClick logic here
              isViewClicked = true;
              view.postDelayed(new Runnable() {
                  @Override
                  public void run() {
                      isViewClicked = false;
                  }
              }, MIN_CLICK_INTERVAL);
          }
          

          }

          【讨论】:

            【解决方案8】:

            尝试设置 yourbutton.setClickable(false) 像这样:

            onclick(){
            yourbutton.setClickable(false) ;
            ButtonLogic();
            }
            
            ButtonLogic(){
            //your button logic
            yourbutton.setClickable(true);
            }
            

            【讨论】:

            • 嘿,我试过了,但如果我快速连续按下按钮,它仍然可以点击。如果您在 onClick() 中进行计算密集型工作,我想禁用按钮或设置不可点击是不够的,因为在禁用按钮之前点击事件可能会排队。有什么想法吗?
            • 我通常使用进度对话框来防止用户在必要时与 UI 交互。如果您正在做的过程比您希望的要长,您可能想尝试一下。
            【解决方案9】:
            public static void disablefor1sec(final View v) {
                    try {
                        v.setEnabled(false);
                        v.setAlpha((float) 0.5);
                        v.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    v.setEnabled(true);
                                    v.setAlpha((float) 1.0);
                                } catch (Exception e) {
                                    Log.d("disablefor1sec", " Exception while un hiding the view : " + e.getMessage());
                                }
                            }
                        }, 1000);
                    } catch (Exception e) {
                        Log.d("disablefor1sec", " Exception while hiding the view : " + e.getMessage());
                    }
                }
            

            我把上面的方法保存在一个静态文件中,我会像这样为所有的按钮点击调用这个方法

                button_or_textview.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        StaticFile.disablefor1sec(button_or_textview);
                        // Do Somthing.
                    }
                });
            

            【讨论】:

              【解决方案10】:

              Qezt 解决方案已经很好了。 但是如果你想防止超快双击,那么你只需降低阈值

                  // half a second
                  if (SystemClock.elapsedRealtime() - doneButtonClickTime < 500) {
                      return;
                  }
              
                  // or 100ms (1/10 of second)
                  if (SystemClock.elapsedRealtime() - doneButtonClickTime < 100) {
                      return;
                  }
              

              【讨论】:

                【解决方案11】:

                Kotlin 短版:

                private var lastClickTime: Long = 0
                    
                //in click listener
                if (SystemClock.elapsedRealtime() - lastClickTime < 1000) {
                    return@setOnClickListener
                }
                lastClickTime = SystemClock.elapsedRealtime()
                

                【讨论】:

                  猜你喜欢
                  • 2022-01-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-10-01
                  • 2018-06-14
                  • 2016-09-05
                  • 1970-01-01
                  • 2016-08-03
                  • 2015-10-17
                  相关资源
                  最近更新 更多