使用倒计时设置按钮启用
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"
我尽量避免重复触摸,但想要一个灵敏的屏幕。使用此答案中建议的方法:
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"