2

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

Android防止双击按钮

4

4 回答 4

5

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

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

于 2011-12-16T02:08:17.400 回答
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 服务仍将只运行一次。

于 2011-12-16T02:12:21.197 回答
1

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

然后对于您的 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 的答案并将其集成到可点击变量更改值的代码中......

于 2015-02-04T16:23:06.950 回答
0

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

于 2011-12-16T03:17:19.983 回答