使用倒计时设置按钮启用

Using countdown to set button enabled

我尽量避免重复触摸,但想要一个灵敏的屏幕。使用此答案中建议的方法:

Android Preventing Double Click On A Button

我一直在程序流程中重新启用按钮,但在某些情况下,我不能依赖程序流程并且需要确保按钮已启用。

我设计了一种使用 countdowntimer 重新启用这些按钮的方法,并在我的代码中显示:

button.setOnTouchListener(new View.OnTouchListener() {
        @Override public boolean onTouch(View v, MotionEvent event) {
            disableButton(button);
            countDwn();
            // Do something
            return false;
        }
    });

public void disableButton(Button button) {
    button.setEnabled(false);
}

public void enableButton(Button button) {
    button.setEnabled(true);
}

public void countDwn() {
    CountDownTimer countDownTimer = new CountDownTimer(2000, 1000) {
        public void onTick(long millisUntilFinished) {
        }

        public void onFinish() {
            enableButton(button);
        }
    }.start();
}

我担心的是,这可能是一种笨拙或无效的方法。我想就此寻求建议,如果有人有更优雅的建议?

我不确定将按钮设置为 enable=false 是解决 "repeated touches" 问题的正确方法。

主要原因是当按钮启用=false 时,大多数时候它会分配一个已禁用的图形。由于我们只想防止意外重复触摸,而不是调用禁用图形,我不确定这是正确的解决方案。

防止重复触摸

我会建议一个更简单的解决方案,如果距上次操作的时间小于 MINIMUM_ACTION_DELAY.

,则阻止该操作

如果要获得点击动画,请阻止onClick 侦听器上的操作。如果您不想要点击动画,请阻止 onTouch 上的操作。

例如,onClick 将是这样的:

button.setOnClickListener(new View.OnClickListener() {

    private long mLastActionTime;

    @Override
    public void onClick(View v) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - mLastActionTime < MINIMUM_ACTION_DELAY) {
            // Too soon, we don't want to handle this event
            return;
        }

        // Save the action time
        mLastActionTime = currentTime;

        // Execute action
        // TODO do something
    }
});

另一种解决方案是创建自定义 Button,您可以随时使用它,而无需重写计时器管理器。可以是这样的:

    public class OneTimeButton extends Button {
    private int timoeut;
    private CountDownTimer timer = null;


    @Override
    public boolean performClick() {
        boolean result = super.performClick();

        if(timer!=null && timoeut > 0){
            setEnabled(false);
            timer.start();
        }

        return result;
    }

    public OneTimeButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.OneTimeButton,
                0, 0);

        try {
            timoeut = a.getInteger(R.styleable.OneTimeButton_timeout, 0);
            setTimer();
        } finally {
            a.recycle();
        }
    }

    private void setTimer() {
        timer = new CountDownTimer(timoeut, timoeut) {
            @Override
            public void onTick(long millisUntilFinished) {}

            @Override
            public void onFinish() {
                setEnabled(true);
            }
        };
    }

    public OneTimeButton(Context context) {
        super(context);
    }

    public OneTimeButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

在 \values 文件夹中定义一个 attrs.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="OneTimeButton">
        <attr name="timeout" format="integer" />
    </declare-styleable>
</resources>

然后,只需在 XML 调用

<it.your_package_name.OneTimeButton 
        android:id="@+id/test_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TEST"
        custom:timeout="5000"/>

您可以将所需的超时(以毫秒为单位)分配给 custom:timeout 属性。

记得在您的布局中(在顶级 ViewGroup 中)声明:

xmlns:custom="http://schemas.android.com/apk/res-auto"