[英]Android: Prevent multiple onClick events on a button (that has been disabled)
一个按钮触发一个应该只调用一次的动作。 在执行操作之前,按钮被禁用并隐藏在 onClick 处理程序中:
someButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
someButton.setEnabled(false);
someButton.setClickable(false);
someButton.setVisibility(View.GONE);
performTaskOnce();
}
});
private void performTaskOnce() {
Log.i("myapp", "Performing task");
//Do something nontrivial that takes a few ms (like changing the view hierarchy)
}
即使按钮立即被禁用,仍然可以通过非常快速地多次点击来触发多个“onClick”事件。 (即performTaskOnce
被多次调用)。 似乎 onClick 事件在按钮实际禁用之前排队。
我可以通过检查每个 onClick 句柄是否已禁用相应的按钮来解决这个问题,但这似乎是一个黑客。 有没有更好的方法来避免这个问题?
问题出现在 Android 2.3.6 上,我无法在 Android 4.0.3 上重现它。 但鉴于 4.x 设备的稀有性,不能排除旧设备。
您可以在单击按钮时将布尔变量设置为 true,并在完成单击处理后将其设置为 false。
通过这种方式,您可以忽略多次点击,而不必禁用按钮,这可能会避免令人讨厌的按钮闪烁。
boolean processClick=true;
someButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(processClick)
{
someButton.setEnabled(false);
someButton.setClickable(false);
someButton.setVisibility(View.GONE);
performTaskOnce();
}
processClick=false;
}
});
private void performTaskOnce() {
Log.i("myapp", "Performing task");
//Do something nontrivial that takes a few ms (like changing the view hierarchy)
}
为了保持干燥:
// Implementation
public abstract class OneShotClickListener implements View.OnClickListener {
private boolean hasClicked;
@Override public final void onClick(View v) {
if (!hasClicked) {
onClicked(v);
hasClicked = true;
}
}
public abstract void onClicked(View v);
}
// Usage example
public class MyActivity extends Activity {
private View myView;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myView.setOnClickListener(new OneShotClickListener() {
@Override public void onClicked(View v) {
// do clicky stuff
}
});
}
}
有点晚了,但这可能对某人有用。 就我而言,我正在调用另一个活动;
声明一个布尔值;
boolean clickable;
在点击监听器中;
if(clickable){
// Launch other activity
clickable = false;
}
调用 onResume 时启用;
@Override
public void onResume() {
Log.e(TAG, "onResume");
super.onResume();
clickable = true;
}
您可以使用RxView
( com.jakewharton.rxbinding2.view.RxView
) 是由 Jake Wharton 创建的围绕 RxJava 的扩展。
要将其集成到项目中,您应该使用implementation 'com.jakewharton.rxbinding3:rxbinding:3.1.0'
简单的Java用法:
RxView.clicks(yourButton)
.sample(500, TimeUnit.MILLISECONDS)
.subscribe { action() }
在Kotlin
您可以创建扩展函数来处理您的点击:
View.singleClick(action: () -> Any) {
RxView.clicks(this)
.sample(500, TimeUnit.MILLISECONDS)
.subscribe { action() }
}
样本:
科特林
yourButton.singleClick({
//do some stuff here
})
爪哇
SingleClickListenerKt.singleClick(yourButton, () -> {
doSomeStuff();
return null;
});
注意:如果您愿意,您可以使用任何 RxJava 运算符,例如 debounce debounce, map, first
等。
声明一个变量并将其用作
boolean boo = false;
someButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(boo==false){
someButton.setEnabled(false);
someButton.setClickable(false);
someButton.setVisibility(View.GONE);
boo = true;
}
}
});
通过这种方式,您可以防止多次点击您的按钮
希望它有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.