У меня есть случай, когда, когда я нажимаю кнопку, она обменивается данными с веб-службой, проблема заключается в том, что если вы дважды щелкните по этой кнопке, она дважды вызывает веб-службы, вызывая двойное представление. Любые идеи, как запретить кнопке принимать второй клик? Я посмотрел на этот пост, но похоже, что решение не работает.
Отключить кнопку недостаточно, вы также должны сделать кнопку незаметной с помощью setClickable(false)
.
setEnabled()
изменит внешний вид кнопки, которая будет продолжать получать события кликов.
На мой взгляд, лучший способ - контролировать, когда запускать веб-сервис. Установите логическое значение для вашего веб-сервиса. Что-то вроде этого (в псевдокоде. Не помните андроида)
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 должны быть синхронизированы таким образом, чтобы вы могли гарантировать, что только один поток обращается к буферизуемому веб-сервису за раз. При этом, даже если пользователю удастся щелкнуть кнопку несколько раз до того, как начнется setClickable (false), ваш веб-сервис будет выполняться только один раз.
Это общее решение, которое вы можете использовать для своего конкретного случая и в любом другом месте вашего кода на любой кнопке, даже если это асинхронный вызов.
Затем для ваших конечных точек webservice, когда вы получаете ответ, тайм-аут или что-то подобное, вызовите пройденную прогон, это снова сбросит вашу кнопку, чтобы снова щелкнуть. См. Следующий класс:
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 и интегрируйте это в этот код, где переменная с кликом меняет значение....
Короче говоря, отключите кнопку при щелчке, затем снова включите ее с помощью обратного вызова из функции/метода обслуживания.