我正在尝试创建一个带有圆圈进度条的计时器。我找到了一个很好的例子来开始 http://www.androidtutorialshub.com/android-count-down-timer-tutorial/。此示例具有我需要的外观,但我想为其添加暂停和恢复功能。所以,我确实有暂停和恢复工作,但是在我单击"暂停"然后"恢复"后,进度条从头开始一秒钟,然后从设置的位置恢复暂停(这是目标)。我的猜测是进度条在某处设置为 100%,然后替换为暂停位置,但我找不到可能发生的部分。
修改的主活动代码:
public class MainActivity extends AppCompatActivity {
private long timeCountInMilliSeconds = 1 * 60000;
long startTime;
long difference;
long difference1;
private enum TimerStatus {
STARTED,
STOPPED,
}
private TimerStatus timerStatus = TimerStatus.STOPPED;
private ProgressBar progressBarCircle;
private EditText editTextMinute;
private TextView textViewTime;
private ImageView imageViewReset;
private ImageView imageViewStartStop;
private CountDownTimer countDownTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBarCircle = (ProgressBar) findViewById(R.id.progressBarCircle);
editTextMinute = (EditText) findViewById(R.id.editTextMinute);
textViewTime = (TextView) findViewById(R.id.textViewTime);
imageViewReset = (ImageView) findViewById(R.id.imageViewReset);
imageViewStartStop = (ImageView) findViewById(R.id.imageViewStartStop);
imageViewReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
reset();
}
});
imageViewStartStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
pauseResume();
}
});
}
private void reset() {
stopCountDownTimer();
restartCountDownTimer();
}
private void pauseResume() {
if (timerStatus == TimerStatus.STOPPED) {
timeCountInMilliSeconds = 1 * 50000;
// setProgressBarValues(timeCountInMilliSeconds);
progressBarCircle.setMax((int) (timeCountInMilliSeconds) / 1000);
progressBarCircle.setProgress((int) (timeCountInMilliSeconds) / 1000);
imageViewReset.setVisibility(View.VISIBLE);
imageViewStartStop.setImageResource(R.drawable.icon_stop);
editTextMinute.setEnabled(false);
timerStatus = TimerStatus.STARTED;
startCountDownTimer();
startTime = System.currentTimeMillis();
} else {
imageViewReset.setVisibility(View.GONE);
imageViewStartStop.setImageResource(R.drawable.icon_start);
editTextMinute.setEnabled(true);
timerStatus = TimerStatus.STOPPED;
stopCountDownTimer();
if(difference == 0) {
difference = System.currentTimeMillis() - startTime;
}
else{
difference1 = System.currentTimeMillis() - startTime;
difference += difference1;}
}
}
private void startCountDownTimer() {
countDownTimer = new CountDownTimer(timeCountInMilliSeconds - difference, 1000) {
@Override
public void onTick(long millisUntilFinished) {
textViewTime.setText(hmsTimeFormatter(millisUntilFinished));
progressBarCircle.setProgress((int) (millisUntilFinished / 1000));
}
@Override
public void onFinish() {
textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds - difference));
// setProgressBarValues(timeCountInMilliSeconds - difference);
progressBarCircle.setMax((int) (timeCountInMilliSeconds - difference) / 1000);
progressBarCircle.setProgress((int) (timeCountInMilliSeconds - difference) / 1000);
imageViewReset.setVisibility(View.GONE);
imageViewStartStop.setImageResource(R.drawable.icon_start);
editTextMinute.setEnabled(true);
timerStatus = TimerStatus.STOPPED;
}
}.start();
countDownTimer.start();
}
private void restartCountDownTimer() {
difference = 0;
difference1 = 0;
countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 1000) {
@Override
public void onTick(long millisUntilFinished) {
textViewTime.setText(hmsTimeFormatter(millisUntilFinished));
progressBarCircle.setProgress((int) (millisUntilFinished / 1000));
}
@Override
public void onFinish() {
textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
// setProgressBarValues(timeCountInMilliSeconds);
progressBarCircle.setMax((int) (timeCountInMilliSeconds) / 1000);
progressBarCircle.setProgress((int) (timeCountInMilliSeconds) / 1000);
imageViewReset.setVisibility(View.GONE);
imageViewStartStop.setImageResource(R.drawable.icon_start);
editTextMinute.setEnabled(true);
timerStatus = TimerStatus.STOPPED;
}
}.start();
countDownTimer.start();
}
private void stopCountDownTimer() {
countDownTimer.cancel();
}
private String hmsTimeFormatter(long milliSeconds) {
String hms = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(milliSeconds),
TimeUnit.MILLISECONDS.toMinutes(milliSeconds) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliSeconds)),
TimeUnit.MILLISECONDS.toSeconds(milliSeconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliSeconds)));
return hms;
}
}
XML 文件与上面提供的链接(指向示例代码的链接)中的文件相同。
任何帮助将不胜感激。
错误可能出在您的pauseResume
中。你说progressBarCircle.setProgress((int) (timeCountInMilliSeconds) / 1000);
.这会将当前进度设置为指定的值。在您的情况下,这意味着与您的最大值相同的值。我认为您应该将整个块向上移动到onCreate
方法中。
timeCountInMilliSeconds = 1 * 50000;
progressBarCircle.setMax((int) (timeCountInMilliSeconds) / 1000);
progressBarCircle.setProgress((int) (timeCountInMilliSeconds) / 1000);
在开始时初始化这些值一次就足够了。
[编辑]
这种行为对我来说似乎很好。假设如果计时器为 47 秒,则按暂停,现在取决于您的时间,计时器可以在 999 毫秒或 001 毫秒暂停(以指向边缘情况)。在第一种情况下,您必须"接近"等待一秒钟,准确地说是 999 毫秒,直到计时器明显切换状态。在秒的情况下,感觉就像应用程序直接响应,因为您只需要等待 001 毫秒。如果要解决此问题,请按如下所示规范化difference
值:
private void pauseResume() {
if (timerStatus == TimerStatus.STOPPED) {
...
} else {
...
difference += (((int) (System.currentTimeMillis() - startTime) / 1000) + 1) * 1000;
}
}
我还删除了无用的difference1
变量。 我所做的另一个改进是,我删除了if else
语句,因为它也没用。 您还可以删除+ 1
,以便始终等待 1 秒钟,然后再看到视觉效果。