Android 如何防止快速双击按钮
我已经看了这里的答案- 并实现了qezt的解决方案,比如,我尝试了Android 如何防止快速双击按钮,android,Android,我已经看了这里的答案- 并实现了qezt的解决方案,比如,我尝试了setEnabled(false)比如- doneButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // mis-clicking prevention, using threshold of 1 second if (
setEnabled(false)
比如-
doneButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// mis-clicking prevention, using threshold of 1 second
if (SystemClock.elapsedRealtime() - doneButtonClickTime < 1000){
return;
}
//store time of button click
doneButtonClickTime = SystemClock.elapsedRealtime();
doneButton.setEnabled(false);
//do actual work
}
});
doneButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
//防止误点击,使用1秒的阈值
if(SystemClock.elapsedRealtime()-doneButtonClickTime<1000){
返回;
}
//按钮点击时间的存储
doneButtonClickTime=SystemClock.elapsedRealtime();
doneButton.setEnabled(false);
//实际工作
}
});
这两种方法都不适用于超快速双击
注意-处理完成后,我不会设置
doneButton.setEnabled(true)
。我只需完成()活动,这样就不会出现按钮过早启用的问题。我就是这样做的,效果非常好
public abstract class OnOneOffClickListener implements View.OnClickListener {
private static final long MIN_CLICK_INTERVAL=600;
private long mLastClickTime;
public static boolean isViewClicked = false;
public abstract void onSingleClick(View v);
@Override
public final void onClick(View v) {
long currentClickTime=SystemClock.uptimeMillis();
long elapsedTime=currentClickTime-mLastClickTime;
mLastClickTime=currentClickTime;
if(elapsedTime<=MIN_CLICK_INTERVAL)
return;
if(!isViewClicked){
isViewClicked = true;
startTimer();
} else {
return;
}
onSingleClick(v);
}
/**
* This method delays simultaneous touch events of multiple views.
*/
private void startTimer() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
isViewClicked = false;
}
}, 600);
}
}
公共抽象类OnOnOnOffClickListener实现了View.OnClickListener{
私有静态最终长最小点击间隔=600;
私人长时间;
公共静态布尔值isViewClicked=false;
公共摘要无效(视图五);
@凌驾
公共最终作废一次点击(视图五){
长currentClickTime=SystemClock.uptimeMillis();
long elapsedTime=当前单击时间mLastClickTime;
mLastClickTime=当前ClickTime;
如果(elapsedTime尝试设置按钮。设置可点击(false)
像这样:
onclick(){
yourbutton.setClickable(false) ;
ButtonLogic();
}
ButtonLogic(){
//your button logic
yourbutton.setClickable(true);
}
我在按钮的侦听器中使用如下函数:
public static long lastClickTime = 0;
public static final long DOUBLE_CLICK_TIME_DELTA = 500;
public static boolean isDoubleClick(){
long clickTime = System.currentTimeMillis();
if(clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){
lastClickTime = clickTime;
return true;
}
lastClickTime = clickTime;
return false;
}
公共静态长lastClickTime=0;
公共静态最终长双击时间增量=500;
公共静态布尔值isDoubleClick(){
长点击时间=System.currentTimeMillis();
如果(单击时间-上次单击时间<双击时间增量){
lastClickTime=单击时间;
返回true;
}
lastClickTime=单击时间;
返回false;
}
Qezt解决方案已经很好了。
但是,如果您想防止超快速双击,那么您只需降低阈值
// half a second
if (SystemClock.elapsedRealtime() - doneButtonClickTime < 500) {
return;
}
// or 100ms (1/10 of second)
if (SystemClock.elapsedRealtime() - doneButtonClickTime < 100) {
return;
}
//半秒钟
if(SystemClock.elapsedRealtime()-doneButtonClickTime<500){
返回;
}
//或100毫秒(1/10秒)
if(SystemClock.elapsedRealtime()-doneButtonClickTime<100){
返回;
}
苏鲁的回答对我很有效,谢谢
我想为正在使用和面临此问题的任何人添加以下答案-
app:mrl\u rippleDelayClick
默认为true。
这意味着,onClick只有在完成显示涟漪之后才会执行。因此,setEnabled(false)
inner onClick将在延迟后执行,因为涟漪没有执行完毕,在此期间,您可以双击视图
设置app:mrl\u rippleDelayClick=“false”
以修复此问题。这意味着单击视图时将立即调用onClick,而不是等待ripple完成显示。可能不是最有效的,但最小的反向:
...
onClick(View v) {
MultiClickPreventer.preventMultiClick(v);
//your op here
}
...
public class MultiClickPreventer {
private static final long DELAY_IN_MS = 500;
public static void preventMultiClick(final View view) {
if (!view.isClickable()) {
return;
}
view.setClickable(false);
view.postDelayed(new Runnable() {
@Override
public void run() {
view.setClickable(true);
}
}, DELAY_IN_MS);
}
}
我将上述方法保存在一个静态文件中,我将为所有按钮单击调用此方法,如下所示
button_or_textview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
StaticFile.disablefor1sec(button_or_textview);
// Do Somthing.
}
});
您可以使用此方法。通过使用post delay,您可以处理双击事件
void debounceEffectForClick(视图){
}Kotlin短版:
private var lastClickTime: Long = 0
//in click listener
if (SystemClock.elapsedRealtime() - lastClickTime < 1000) {
return
}
lastClickTime = SystemClock.elapsedRealtime()
private var lastClickTime:Long=0
//在“单击侦听器”中
if(SystemClock.elapsedRealtime()-lastClickTime<1000){
返回
}
lastClickTime=SystemClock.elapsedRealtime()
将清单中活动的启动模式设置为singleTop
<activity
android:name="com.example.MainActivity"
android:screenOrientation="portrait"
android:launchMode="singleTop"/>
}为什么setEnabled(false)
不工作?在哪里应用setEnabled(false)你可以马上给我event@Blackbelt似乎回答了为什么。@Blackbelt它不起作用。请查看我在第一条评论中链接到的评论。嘿,我已经尝试过了,但是如果我连续快速按下按钮,按钮仍然可以单击。我想如果你正在做计算密集型工作,禁用按钮或设置不可单击是不够的k在onClick()中因为点击事件可以在按钮被禁用之前排队。有什么想法吗?我通常使用一个进度对话框来阻止用户在必要时与UI交互。如果你正在做的过程比你希望的要长,你可能想尝试一下。这更像是一个评论,而不是一个回答。发布你的答案比公布你的答案更好t、 因为我在MaterialRippleLayout上遇到了同样的问题,我找到了单独的解决方案。谢谢@Mallika。这在反转返回布尔值后对我有效。我已编辑了答案。
private var lastClickTime: Long = 0
//in click listener
if (SystemClock.elapsedRealtime() - lastClickTime < 1000) {
return
}
lastClickTime = SystemClock.elapsedRealtime()
<activity
android:name="com.example.MainActivity"
android:screenOrientation="portrait"
android:launchMode="singleTop"/>
private static final long MIN_CLICK_INTERVAL = 1000;
private boolean isViewClicked = false;
private View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
final public void onClick(View view) {
if (isViewClicked) {
return:
}
// place your onClick logic here
isViewClicked = true;
view.postDelayed(new Runnable() {
@Override
public void run() {
isViewClicked = false;
}
}, MIN_CLICK_INTERVAL);
}