在安卓系统中防止双击按钮的最佳方法是什么?
当前回答
下面是一个OnClickListener代理,它可以根据qezt的答案阻止连续的单击。
import android.os.SystemClock;
import android.view.View;
public class MultiClickGuard implements View.OnClickListener {
private long mLastClickTime;
private final int mThresholdMillis;
private final View.OnClickListener mListener;
public MultiClickGuard(View.OnClickListener listener, int thresholdMillis) {
if (listener == null) {
throw new NullPointerException("Null OnClickListener");
}
if (thresholdMillis < 0) {
throw new IllegalArgumentException("Negative click threshold: " + thresholdMillis);
}
mListener = listener;
mThresholdMillis = thresholdMillis;
}
@Override
public void onClick(View v) {
// Using a time threshold to prevent successive clicks.
if (SystemClock.elapsedRealtime() - mLastClickTime < mThresholdMillis) {
return;
}
mLastClickTime = SystemClock.elapsedRealtime();
// Forward the click event to the *real* listener.
mListener.onClick(v);
}
}
用法示例
button.setOnClickListener(new MultiClickGuard(new View.OnClickListener() {
@Override
public void onClick(View v) {
// do something
}
}, 1000));
button.setOnClickListener(new MultiClickGuard(v -> {...}, 1000));
button.setOnClickListener(new MultiClickGuard(v -> doSomething(), 1000));
在试图阻止启动一个活动的多个实例的情况下,考虑指定启动模式:理解任务和返回堆栈,这是可靠的方式。
如果您试图阻止打开一个对话框片段的多个实例,您可以检查片段管理器是否已经包含了对话框,例如getSupportFragmentManager(). findfragmentbytag (tag)。
其他回答
Kotlin创建类SafeClickListener
class SafeClickListener(
private var defaultInterval: Int = 1000,
private val onSafeCLick: (View) -> Unit
) : View.OnClickListener {
private var lastTimeClicked: Long = 0 override fun onClick(v: View) {
if (SystemClock.elapsedRealtime() - lastTimeClicked < defaultInterval) {
return
}
lastTimeClicked = SystemClock.elapsedRealtime()
onSafeCLick(v)
}
}
在baseClass或else中创建一个函数
fun View.setSafeOnClickListener(onSafeClick: (View) -> Unit) {val safeClickListener = SafeClickListener {
onSafeClick(it)
}
setOnClickListener(safeClickListener)
}
并使用按钮点击
btnSubmit.setSafeOnClickListener {
showSettingsScreen()
}
对我来说,只有记住时间戳并检查它(距离上次点击超过1秒)才有帮助。
只有2步,你可以在你的应用程序的任何地方使用它。
步骤1。创建一个单例管理器[避免多次点击]
package com.im.av.mediator;
import android.os.SystemClock;
import java.util.HashMap;
/**
* Created by ShuHeng on 16/6/1.
*/
public class ClickManager {
private HashMap<Integer,Long> laskClickTimeMap=new HashMap<Integer,Long>();
public volatile static ClickManager mInstance =null;
public static ClickManager getInstance(){
if (mInstance == null) {
synchronized(ClickManager.class) {
if (mInstance == null) {
mInstance = new ClickManager();
}
}
}
return mInstance;
}
public boolean isClickable1s(Integer key){
Long keyLong = laskClickTimeMap.get(key);
if(keyLong==null){
laskClickTimeMap.put(key,SystemClock.elapsedRealtime());
return true;
}else{
if (SystemClock.elapsedRealtime() - keyLong.longValue() < 1000){
return false;
}else{
laskClickTimeMap.put(key,new Long(SystemClock.elapsedRealtime()));
return true;
}
}
}
}
步骤2。添加一行,避免多次单击。
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int id = v.getId();
if (id == R.id.iv_back) {
if(!ClickManager.getInstance().isClickable1s(R.id.iv_back))return;
//do something
} else if (id == R.id.iv_light) {
if(!ClickManager.getInstance().isClickable1s(R.id.iv_light))return;
//do something
} else if (id == R.id.iv_camerarotate) {
if(!ClickManager.getInstance().isClickable1s(R.id.iv_camerarotate))return;
//do something
} else if (id == R.id.btn_delete_last_clip) {
if(!ClickManager.getInstance().isClickable1s(R.id.btn_delete_last_clip))return;
//do something
} else if (id == R.id.iv_ok) {
if(!ClickManager.getInstance().isClickable1s(R.id.iv_ok))return;
//do something
}
}
对于任何使用数据绑定的用户:
@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()}"
... />
当UI线程阻塞时,单击事件队列。对于按钮单击事件,请尽快将其更改为后台任务,以避免单击事件在彼此后面排队。
在activity类中声明一个volatile boolean或lock:
private volatile boolean saving = false;
创建一个onClickListener按钮,通过保存和启动一个后台任务来完成工作:
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!saving) {
saving = true;
new SaveAsyncTask().execute();
}
}
});
创建一个内部的SaveAsyncTask类来在后台完成工作:
class SaveAsyncTask extends AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
// Do something here, simulate a 3 second task
SystemClock.sleep(3000);
saving = false;
return null;
}
}
推荐文章
- 在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()函数的使用感到困惑
- 为什么构建类型与产品风味不同?