Using countdown to set button enabled

不羁的心 提交于 2019-12-06 11:31:08

I am not sure setting a button to enable=false is the correct way to solve the "repeated touches" issue.

The main reason for that is since when a button is enable=false, most of the time it will have a Disabled graphics assigned to it. Since we only want to prevent accidental repeated touches, and not to invoke the disable graphics, I am not sure this is the correct solution.

Prevent Repeated Touches

I will suggest a simpler solution, prevent the action if the time from last action is less than MINIMUM_ACTION_DELAY.

If you want to get the click animation, prevent the action on the onClick listener. If you don't want the click animation, prevent the action on the onTouch.

For example, onClick will be something like this:

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

Another solution is to create a custom Button, that you can use all times you want, without rewrite the timer manager. Can be something like this:

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

Define an attrs.xml file in \values folder:

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

Then, simply in your XML call

<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"/>

You can assign the timeout you want (in milliseconds) to custom:timeout attribute.

Remember to declare in your layout (at the top level ViewGroup) this:

xmlns:custom="http://schemas.android.com/apk/res-auto"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!