在安卓系统中防止双击按钮的最佳方法是什么?
当前回答
防止点击乘法btns
使用:
private val disposables = CompositeDisposable()
private val clickInteractor = ClickInteractor(disposables)
...
button1.setOnClickListener{
clickInteractor.click {
Toast.makeText(context, "Btn1", Toast.LENGTH_LONG).show()
}
}
button2.setOnClickListener{
clickInteractor.click {
Toast.makeText(context, "Btn2", Toast.LENGTH_LONG).show()
}
}
ClickInteractor.kt:
class ClickInteractor constructor(disposables: CompositeDisposable) {
private val performPublish = PublishSubject.create<ClickInteractorCallback>()
init {
performPublish
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.throttleFirst(1, TimeUnit.SECONDS, Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext { callback ->
callback.invoke()
}
.retry()
.execute(disposables)
}
fun click(callback: ClickInteractorCallback) {
performPublish.onNext(callback)
}
}
typealias ClickInteractorCallback = () -> Unit
其他回答
我的解决方案是尝试使用一个布尔变量:
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)
}
}
下面是kotlin扩展函数的方式,将工作于所有视图,保持以下函数在您的Utils或任何文件
fun View.preventDoubleClick() {
this.isEnabled = false
this.postDelayed( { this.isEnabled = true }, 1000)
}
下面是如何从片段或活动中使用它
anyIdOfView?.setOnClickListener {
it.preventDoubleClick()
YourAction()
}
具有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() }
对于任何使用数据绑定的用户:
@BindingAdapter("onClickWithDebounce")
fun onClickWithDebounce(view: View, listener: android.view.View.OnClickListener) {
view.setClickWithDebounce {
listener.onClick(view)
}
}
object LastClickTimeSingleton {
var lastClickTime: Long = 0
}
fun View.setClickWithDebounce(action: () -> Unit) {
setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
if (SystemClock.elapsedRealtime() - LastClickTimeSingleton.lastClickTime < 500L) return
else action()
LastClickTimeSingleton.lastClickTime = SystemClock.elapsedRealtime()
}
})
}
<androidx.appcompat.widget.AppCompatButton
..
android:text="@string/signup_signin"
app:onClickWithDebounce="@{() -> viewModel.onSignUpClicked()}"
... />
这个问题的实际解决方案是使用setEnabled(false),灰色按钮,和setClickable(false),使它第二次点击不能接收,我已经测试过了,它似乎是非常有效的。
推荐文章
- 在Android Studio中创建aar文件
- 修改抽射超时时间
- 如何通过数据从第二个活动到第一个活动时按回?——安卓
- 如何在android中获得当前前景活动上下文?
- 如何在Android中获取当前日期?
- 获取Android设备名称
- 在WebView中上传文件
- 加载HTML文件到WebView
- Android:为什么视图没有maxHeight ?
- 如何获得具有已知资源名称的资源id ?
- 在Android上将字符串转换为整数
- 为什么“System.out。”println“工作在Android?
- WebView显示err_cleartext_not_allowed尽管站点是HTTPS
- Android M权限:对shouldShowRequestPermissionRationale()函数的使用感到困惑
- 为什么构建类型与产品风味不同?