I am trying to avoid repeated touches, but want a sensitive screen. Using the method advised in this answer:
Android Preventing Double Click On A Button
I have been re-enabling buttons within the program flow, but there are some instances where, I cannot rely on program flow and need to ensure the button is enabled.
I have devised a way to re-enable these button using a countdowntimer
and shown in my code:
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();
}
What I am concerned about, is that this may be a clumsy or ineffective way to go about this. I am wanting advice about this and if anyone has a more elegant suggestion?
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"
来源:https://stackoverflow.com/questions/31491182/using-countdown-to-set-button-enabled