在安卓系统中防止双击按钮的最佳方法是什么?
当前回答
我更喜欢使用信号量块。它是线程安全的,不仅可以用于按钮。
代码示例很简单:
private UtilsSemaphore buttonSemaphore = new UtilsSemaphore();
public void onClick(View view)
{
boolean isAllowed = buttonSemaphore.lock();
if(!isAllowed)
{
return;
}
final View clickedButton = view;
clickedButton.setEnabled(false);
/* some code */
buttonSemaphore.unlock();
clickedButton.setEnabled(true);
}
public class UtilsSemaphore {
public int counter = 0;
public boolean lock()
{
int counterValue = ++counter;
boolean isAllowed = counterValue < 2;
if(!isAllowed)
{
unlock();
}
return isAllowed;
}
public void unlock()
{
--counter;
}
}
其他回答
在点击的时候保存最后一次点击的时间可以避免这个问题。
i.e.
private long mLastClickTime = 0;
...
// inside onCreate or so:
findViewById(R.id.button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// mis-clicking prevention, using threshold of 1000 ms
if (SystemClock.elapsedRealtime() - mLastClickTime < 1000){
return;
}
mLastClickTime = SystemClock.elapsedRealtime();
// do your magic here
}
}
在我的情况下,我使用按钮视图,它的点击速度太快了。只需禁用点击,并在几秒钟后再次启用它…
基本上我做了一个包装类,包装你的Views onClickListener。如果您愿意,还可以设置自定义延迟。
public class OnClickRateLimitedDecoratedListener implements View.OnClickListener {
private final static int CLICK_DELAY_DEFAULT = 300;
private View.OnClickListener onClickListener;
private int mClickDelay;
public OnClickRateLimitedDecoratedListener(View.OnClickListener onClickListener) {
this(onClickListener, CLICK_DELAY_DEFAULT);
}
//customize your own delay
public OnClickRateLimitedDecoratedListener(View.OnClickListener onClickListener, int delay) {
this.onClickListener = onClickListener;
mClickDelay = delay;
}
@Override
public void onClick(final View v) {
v.setClickable(false);
onClickListener.onClick(v);
v.postDelayed(new Runnable() {
@Override
public void run() {
v.setClickable(true);
}
}, mClickDelay);
}
}
简单地调用它:
mMyButton.setOnClickListener(new OnClickRateLimitedDecoratedListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doSomething();
}
}));
或者提供你自己的延迟:
mMyButton.setOnClickListener(new OnClickRateLimitedDecoratedListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doSomething();
}
},1000));
更新:以上方式有点过时,现在RxJava是如此流行。正如其他人所提到的,在android中我们可以使用油门来减慢点击。这里有一个例子:
RxView.clicks(myButton)
.throttleFirst(2000, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
.subscribe {
Log.d("i got delayed clicked")
}
}
实现'com. jake沃顿。rxbinding:2.0.0'
结合Gustavo的答案,我已经在Kotlin中实现了看起来非常干净的扩展:
fun View.setOnSingleClickListener(l: () -> Unit) {
setOnClickListener { view ->
l.invoke(view)
isEnabled = false
postDelayed({
isEnabled = true
}, 600)
}
}
这是你如何设置这个点击监听器:
yourView.setOnSingleClickListener {
// Insert your code here
}
具有Kotlin扩展功能:
fun View.onSingleClick(action: (v: View) -> Unit) {
setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
isClickable = false
action(v)
postDelayed({ isClickable = true }, 700)
}
})
}
用法:
button.onSingleClick { myAction() }
如果按钮做的唯一一件事是启动一个新活动,这个问题可以通过“singleTop”活动启动模式和在意图上设置FLAG_ACTIVITY_CLEAR_TOP来解决。这种方法不适用于复杂活动的层次结构,但适用于简单的树状应用程序结构。
推荐文章
- 在android中从上下文获取活动
- 无法解析主机"<URL here>"没有与主机名关联的地址
- getActivity()在Fragment函数中返回null
- 按钮背景是透明的
- 在Mac OS X上哪里安装Android SDK ?
- 我如何获得图像缩放功能?
- 在Android应用程序中显示当前时间和日期
- BottomSheetDialogFragment的圆角
- 在应用程序启动时出现“无法获得BatchedBridge,请确保您的bundle被正确打包”的错误
- 我如何改变默认对话框按钮的文本颜色在安卓5
- 更改单选按钮的圆圈颜色
- 如何在android中复制一个文件?
- adb找不到我的设备/手机(MacOS X)
- 如何在新的材质主题中改变背面箭头的颜色?
- androidviewpager与底部点