在安卓系统中防止双击按钮的最佳方法是什么?
当前回答
你可以使用这种方法。通过使用后延迟,你可以照顾双击事件。
void debounceEffectForClick(查看视图){
view.setClickable(false);
view.postDelayed(new Runnable() {
@Override
public void run() {
view.setClickable(true);
}
}, 500);
}
其他回答
我用两个类来解决这个问题,一个类似于@jinshiyi11的答案,另一个是基于显式点击,在这里你只能点击一个按钮一次,如果你想要另一次点击,你必须显式地指出它。
/**
* Listener que sólo permite hacer click una vez, para poder hacer click
* posteriormente se necesita indicar explicitamente.
*
* @author iberck
*/
public abstract class OnExplicitClickListener implements View.OnClickListener {
// you can perform a click only once time
private boolean canClick = true;
@Override
public synchronized void onClick(View v) {
if (canClick) {
canClick = false;
onOneClick(v);
}
}
public abstract void onOneClick(View v);
public synchronized void enableClick() {
canClick = true;
}
public synchronized void disableClick() {
canClick = false;
}
}
使用示例:
OnExplicitClickListener clickListener = new OnExplicitClickListener() {
public void onOneClick(View v) {
Log.d("example", "explicit click");
...
clickListener.enableClick();
}
}
button.setOnClickListener(clickListener);
这是我的解决方案:
if (waitDouble) {
waitDouble = false;
Thread thread = new Thread() {
@Override
public void run() {
try {
sleep(300);
if (waitDouble == false) {
waitDouble = true;
singleClick(); //singleClick
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
} else {//DoubleClick
DoubleClick();
waitDouble = true;
}
或者另一种解决方案:
public class NoDoubleClickUtils {
private static long lastClickTime;
private final static int SPACE_TIME = 500;
public static void initLastClickTime() {
lastClickTime = 0;
}
public synchronized static boolean isDoubleClick() {
long currentTime = System.currentTimeMillis();
boolean isClick2;
if (currentTime - lastClickTime > SPACE_TIME) {
isClick2 = false;
} else {
isClick2 = true;
}
lastClickTime = currentTime;
return isClick2;
}
}
我的解决方案是尝试使用一个布尔变量:
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)
}
}
防止点击乘法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
我知道这是一个老问题,但我分享了我找到的解决这个常见问题的最佳方案
btnSomeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Prevent Two Click
Utils.preventTwoClick(view);
// Do magic
}
});
在另一个文件中,比如Utils.java
/**
* Método para prevenir doble click en un elemento
* @param view
*/
public static void preventTwoClick(final View view){
view.setEnabled(false);
view.postDelayed(
()-> view.setEnabled(true),
500
);
}
推荐文章
- 改变开关的“开”色
- 以编程方式将EditText的输入类型从PASSWORD更改为NORMAL,反之亦然
- 如何在隐藏和查看密码之间切换
- 在Android上调整一个大的位图文件到缩放输出文件
- 如何更改Android版本和代码版本号?
- Android Studio突然无法解析符号
- 应用程序重新启动而不是恢复
- 如何设置整个应用程序在纵向模式?
- Android中文本的阴影效果?
- 以编程方式设置TextView的布局权重
- Android -如何覆盖“后退”按钮,所以它不完成()我的活动?
- 如何从通知点击发送参数到一个活动?
- 导航目标xxx对于这个NavController是未知的
- 使用ConstraintLayout均匀间距的视图
- 文件google-services错误。模块根文件夹中缺少Json。谷歌服务插件没有它就不能正常工作。