首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >避免按钮多次快速点击

避免按钮多次快速点击
EN

Stack Overflow用户
提问于 2013-05-14 10:55:04
回答 17查看 65K关注 0票数 96

我的应用程序有一个问题,如果用户快速地多次单击按钮,那么在我的按住按钮的对话框消失之前就会生成多个事件

我知道一个解决方案,当一个按钮被点击时,将一个布尔变量设置为一个标志,这样就可以在对话框关闭之前阻止以后的点击。然而,我有很多按钮,每次都要为每个按钮做这件事似乎有点过头了。在android中有没有其他方法(或者可能是更聪明的解决方案)来只允许每次点击按钮时生成事件操作?

更糟糕的是,在处理第一个操作之前,多个快速单击似乎会生成多个事件操作,所以如果我想禁用第一个单击处理方法中的按钮,队列中已经有现有的事件操作等待处理!

请帮帮忙谢谢

EN

回答 17

Stack Overflow用户

回答已采纳

发布于 2013-05-14 11:08:14

这是我最近写的一个“被揭穿”的onClick监听器。您可以告诉它,两次单击之间可接受的最小毫秒数是多少。用onDebouncedClick而不是onClick实现你的逻辑

代码语言:javascript
复制
import android.os.SystemClock;
import android.view.View;

import java.util.Map;
import java.util.WeakHashMap;

/**
 * A Debounced OnClickListener
 * Rejects clicks that are too close together in time.
 * This class is safe to use as an OnClickListener for multiple views, and will debounce each one separately.
 */
public abstract class DebouncedOnClickListener implements View.OnClickListener {

    private final long minimumIntervalMillis;
    private Map<View, Long> lastClickMap;

    /**
     * Implement this in your subclass instead of onClick
     * @param v The view that was clicked
     */
    public abstract void onDebouncedClick(View v);

    /**
     * The one and only constructor
     * @param minimumIntervalMillis The minimum allowed time between clicks - any click sooner than this after a previous click will be rejected
     */
    public DebouncedOnClickListener(long minimumIntervalMillis) {
        this.minimumIntervalMillis = minimumIntervalMillis;
        this.lastClickMap = new WeakHashMap<>();
    }

    @Override 
    public void onClick(View clickedView) {
        Long previousClickTimestamp = lastClickMap.get(clickedView);
        long currentTimestamp = SystemClock.uptimeMillis();

        lastClickMap.put(clickedView, currentTimestamp);
        if(previousClickTimestamp == null || Math.abs(currentTimestamp - previousClickTimestamp) > minimumIntervalMillis) {
            onDebouncedClick(clickedView);
        }
    }
}
票数 119
EN

Stack Overflow用户

发布于 2016-03-01 01:09:02

使用RxBinding可以很容易地完成此任务。下面是一个示例:

代码语言:javascript
复制
RxView.clicks(view).throttleFirst(500, TimeUnit.MILLISECONDS).subscribe(empty -> {
            // action on click
        });

build.gradle中添加以下行,以添加RxBinding依赖:

代码语言:javascript
复制
compile 'com.jakewharton.rxbinding:rxbinding:0.3.0'
票数 73
EN

Stack Overflow用户

发布于 2013-12-03 18:12:41

这是我接受的答案的版本。它非常类似,但没有尝试将视图存储在Map中,我认为这不是一个好主意。它还添加了一个在许多情况下都很有用的wrap方法。

代码语言:javascript
复制
/**
 * Implementation of {@link OnClickListener} that ignores subsequent clicks that happen too quickly after the first one.<br/>
 * To use this class, implement {@link #onSingleClick(View)} instead of {@link OnClickListener#onClick(View)}.
 */
public abstract class OnSingleClickListener implements OnClickListener {
    private static final String TAG = OnSingleClickListener.class.getSimpleName();

    private static final long MIN_DELAY_MS = 500;

    private long mLastClickTime;

    @Override
    public final void onClick(View v) {
        long lastClickTime = mLastClickTime;
        long now = System.currentTimeMillis();
        mLastClickTime = now;
        if (now - lastClickTime < MIN_DELAY_MS) {
            // Too fast: ignore
            if (Config.LOGD) Log.d(TAG, "onClick Clicked too quickly: ignored");
        } else {
            // Register the click
            onSingleClick(v);
        }
    }

    /**
     * Called when a view has been clicked.
     * 
     * @param v The view that was clicked.
     */
    public abstract void onSingleClick(View v);

    /**
     * Wraps an {@link OnClickListener} into an {@link OnSingleClickListener}.<br/>
     * The argument's {@link OnClickListener#onClick(View)} method will be called when a single click is registered.
     * 
     * @param onClickListener The listener to wrap.
     * @return the wrapped listener.
     */
    public static OnClickListener wrap(final OnClickListener onClickListener) {
        return new OnSingleClickListener() {
            @Override
            public void onSingleClick(View v) {
                onClickListener.onClick(v);
            }
        };
    }
}
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16534369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档