使用倒计时设置按钮启用

时间:2015-07-18 12:30:15

标签: android algorithm performance ontouchlistener countdowntimer

我试图避免重复触摸,但想要一个敏感的屏幕。使用本答案中建议的方法:

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();
}

我关心的是,这可能是一种笨拙或无效的方式。我想要这个建议,如果有人有更优雅的建议吗?

2 个答案:

答案 0 :(得分:2)

我不确定设置按钮enable = false是解决"重复触摸" 问题的正确方法。

主要原因是,当一个按钮为enable = false时,大部分时间都会为其分配一个Disabled图形。由于我们只想防止意外重复触摸,而不是调用禁用图形,我不确定这是正确的解决方案。

防止重复接触

我会建议一个更简单的解决方案,如果上一次操作的时间小于 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
    }
});

答案 1 :(得分:1)

另一个解决方案是创建一个自定义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"