【问题标题】:Android: Button Double SubmittingAndroid:按钮双重提交
【发布时间】:2011-12-16 02:01:39
【问题描述】:

我有一种情况,当我按下一个按钮时,它会与 Web 服务通信,我遇到的问题是,如果你双击该按钮,它会调用 Web 服务两次,从而导致双重提交。任何想法如何防止按钮接受第二次点击?我看了这篇文章,但似乎解决方案不起作用。

Android Preventing Double Click On A Button

【问题讨论】:

    标签: android android-button


    【解决方案1】:

    禁用按钮是不够的,您还应该使用setClickable(false) 使按钮无法点击。

    setEnabled()只会改变按钮的外观,会继续接收点击事件。

    【讨论】:

    • LadaRaider,这很好用。它很简单,而且很简单。谢谢!
    【解决方案2】:

    我认为最好的方法是控制何时运行您的 Web 服务。为您的 Web 服务通信设置一个布尔值。像这样的东西(在伪代码中。不太记得android)

    private boolean webServiced = false;
    
    public synchronized void startWebService(){
        if (!webServiced){
            webServiced = true;
            //run your web service call on separate thread or something
        }
    }
    
    public synchronized void onWebServiceDone(){
        webServiced = false;
        myButton.setClickable(true)
    }
    
    public void onButtonClick(Event e){
        startWebService();
        myButton.setClickable(false)
    }
    

    这里重要的是 webService 方法需要同步,这样才能确保一次只有一个线程访问 webServiced 布尔值。这样,即使用户在 setClickable(false) 启动之前多次单击按钮,您的 Web 服务仍然只会运行一次。

    【讨论】:

    • 我认为这可行,但它是一个过于复杂的解决方案。我将奖励 LadaRaider 正确。
    【解决方案3】:

    这是一个通用解决方案,您可以将其用于您的特定情况以及代码中任何按钮的其他位置,即使事件是异步调用也是如此。

    然后对于您的 Web 服务端点,当您收到回复、超时等时,调用传递的可运行对象,这会将您的按钮重置为可再次单击。请参阅下面的课程:

    public abstract class OneClickListener implements View.OnClickListener {
    
    private boolean clickable = true;
    private Runnable reactivateButtonRunnable;
    
    @Override
    public final void onClick(final View v) {
        if (clickable) {
            clickable = false;
            reactivateButtonRunnable = new Runnable() {
                @Override
                public void run() {
                    reset();
                }
            };
            onOneClick(v, reactivateButtonRunnable);
        }
    }
    
    public abstract void onOneClick(View v, final Runnable reactivateButtonRunnable);
    
    // reset listener to accept new clicks
    public void reset() {
        clickable = true;
    }
    }
    

    示例伪代码,只是为了说明原理:

    Button button = new Button(this);
    button.setOnClickListener(new OneClickListener() {
            @Override
            public void onOneClick(View v, Runnable reactivateButtonRunnable) {
                launchWebService(reactivateButtonRunnable);
            }
        });
    
    public void launchWebService(final Runnable reactivateButton){
        // 
        doRequest(new OnResponseListener(){
         @Override
         public void onSuccess(){
            // your custom code
            reactivateButton.run();  // makes button clickable again here
         }
         @Override
         public void onTimeout(){
            // your custom code
            reactivateButton.run();  // makes button clickable again here
         }
         @Override
         public void onFailure(){
            // your custom code
            reactivateButton.run();  // makes button clickable again here
         }
    });
    }
    

    注意:这不会阻止 Android 对按钮上的点击事件进行排队,但会阻止您的代码执行。

    如果您还想禁用按钮,请参阅 Dalmas 的回答并将其集成到可点击变量更改值的代码中......

    【讨论】:

      【解决方案4】:

      简而言之,禁用单击按钮,然后使用服务使用者函数/方法的回调重新启用它。

      【讨论】:

      • 启用和禁用按钮不足以防止第二次点击。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      相关资源
      最近更新 更多