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