在安卓系统中防止双击按钮的最佳方法是什么?
当前回答
我的解决方案是尝试使用一个布尔变量:
public class Blocker {
private static final int DEFAULT_BLOCK_TIME = 1000;
private boolean mIsBlockClick;
/**
* Block any event occurs in 1000 millisecond to prevent spam action
* @return false if not in block state, otherwise return true.
*/
public boolean block(int blockInMillis) {
if (!mIsBlockClick) {
mIsBlockClick = true;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mIsBlockClick = false;
}
}, blockInMillis);
return false;
}
return true;
}
public boolean block() {
return block(DEFAULT_BLOCK_TIME);
}
}
并使用如下:
view.setOnClickListener(new View.OnClickListener() {
private Blocker mBlocker = new Blocker();
@Override
public void onClick(View v) {
if (!mBlocker.block(block-Time-In-Millis)) {
// do your action
}
}
});
更新:Kotlin解决方案,使用视图扩展
fun View.safeClick(listener: View.OnClickListener, blockInMillis: Long = 500) {
var lastClickTime: Long = 0
this.setOnClickListener {
if (SystemClock.elapsedRealtime() - lastClickTime < blockInMillis) return@setOnClickListener
lastClickTime = SystemClock.elapsedRealtime()
listener.onClick(this)
}
}
其他回答
这个问题的实际解决方案是使用setEnabled(false),灰色按钮,和setClickable(false),使它第二次点击不能接收,我已经测试过了,它似乎是非常有效的。
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
//to prevent double click
button.setOnClickListener(null);
}
});
这个解决方案(Kotlin)对我很有效:
abstract class SingleClickListener : View.OnClickListener {
private val MIN_CLICK_INTERVAL: Long = 1000
private var mLastClickTime: Long = 0
abstract fun onSingleClick(v: View?)
override fun onClick(v: View?) {
if (mLastClickTime <= 0) {
mLastClickTime = SystemClock.uptimeMillis()
onSingleClick(v)
return
}
if (SystemClock.uptimeMillis() - mLastClickTime <= MIN_CLICK_INTERVAL) {
return
}
mLastClickTime = SystemClock.uptimeMillis()
onSingleClick(v)
}
}
用法:
someView.setOnClickListener(object : SingleClickListener() {
override fun onSingleClick(v: View?) {
v?.also { klik(it) }
}
})
或者也可以创建扩展函数,在视图上轻松添加ClickListener:
fun View.click(klik: (View) -> Unit) {
this.setOnClickListener(object : SingleClickListener() {
override fun onSingleClick(v: View?) {
v?.also { klik(it) }
}
})
}
// Usage
class XPerimentActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_xperiment_layout)
submit_button.click {
// do your magic
}
}
}
你可以用Kotlin扩展函数和RxBinding来实现它
fun View.clickWithDebounce(debounceTime: Long = 600L, action: () -> Unit): Disposable =
RxView.clicks(this)
.debounce(debounceTime, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { action() }
or
fun View.clickWithDebounce(debounceTime: Long = 600L, action: () -> Unit) {
this.setOnClickListener(object : View.OnClickListener {
private var lastClickTime: Long = 0
override fun onClick(v: View) {
if (SystemClock.elapsedRealtime() - lastClickTime < debounceTime) return
else action()
lastClickTime = SystemClock.elapsedRealtime()
}
})
}
然后就是:
View.clickWithDebounce{ Your code }
试试这个,它是有效的:
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mSlotLayout.setEnabled(false);
// do your work here
Timer buttonTimer = new Timer();
buttonTimer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mButton.setEnabled(true);
}
});
}
}, 500); // delay button enable for 0.5 sec
}
});
推荐文章
- 改变开关的“开”色
- 以编程方式将EditText的输入类型从PASSWORD更改为NORMAL,反之亦然
- 如何在隐藏和查看密码之间切换
- 在Android上调整一个大的位图文件到缩放输出文件
- 如何更改Android版本和代码版本号?
- Android Studio突然无法解析符号
- 应用程序重新启动而不是恢复
- 如何设置整个应用程序在纵向模式?
- Android中文本的阴影效果?
- 以编程方式设置TextView的布局权重
- Android -如何覆盖“后退”按钮,所以它不完成()我的活动?
- 如何从通知点击发送参数到一个活动?
- 导航目标xxx对于这个NavController是未知的
- 使用ConstraintLayout均匀间距的视图
- 文件google-services错误。模块根文件夹中缺少Json。谷歌服务插件没有它就不能正常工作。