Android 中的 CountDownTimer 使用 Java

CountDownTimer in Android using Java

我正在尝试在 android 中实现一个计时器。我正在使用倒数计时器。这是定时器代码:

 new CountDownTimer(totalTime * 1000, 1000) {
        @Override
        public void onTick(long l) {
            int newSec = (int) (sec - (sec - (l / 1000)));
            if(l % 60 == 0) {
                min--;
            }
            if(newSec < 10) {
                tv_timer.setText(min + ":" + z + newSec);
            } else {
                tv_timer.setText(min + ":" + newSec);
            }
        }

        @Override
        public void onFinish() {
            mediaPlayer.start();
        }
    }.start();

计时器不断更新用户屏幕上剩余的时间。

问题是定时器一直在 00:01(1 秒)结束,它从不显示 00:00,并且在定时器结束 2 秒后闹钟响起。

如何让00:00显示出来,以及如何让闹钟在定时器结束后立即响起?

这是搜索栏代码。 seekbar被用户用来设置定时器:

seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            z = 0;
            min = i / 60;
            sec = i - min * 60;
            if(sec < 10) {
                tv_timer.setText(min + ":" + z + sec);
            } else {
                tv_timer.setText(min + ":" + sec);

            }
            totalTime = i;
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });

如图CountDownTimer documentation

onTick(long millisUntilFinished)

millisUntilFinished long: The amount of time until finished.

这意味着 00:00 永远不会显示在您的代码中,因为 onTick 在没有剩余时间完成时不会被调用。

只需在 onFinish

中显示 00:00
@Override
        public void onFinish() {
            tv_timer.setText("00:00");
            mediaPlayer.start();
        }

关于闹钟的提示音,好像是倒计时结束后立即响起。您必须检查音调本身是否在开始时没有一两秒的静音。

跟进@ShadySherif 的(正确)回答,添加一些基本日志记录将有助于理解行为并突出显示代码中的可疑语句。

片段:

// Countdown 10 seconds providing an update every second until finished.
new CountDownTimer(10 * 1000, 1000) {
    @Override
    public void onTick(long millisUntilFinished) {
       Log.d("sotest",Long.toString(millisUntilFinished));
    }

    @Override
    public void onFinish() {
        Log.d("sotest","Finish");
    }
}.start();

Log(注意 millisUntilFinished 值会因 运行 而异):

2020-07-10 09:32:46.628 9087-9087/calculations D/sotest: 9986
2020-07-10 09:32:47.629 9087-9087/calculations D/sotest: 8985
2020-07-10 09:32:48.630 9087-9087/calculations D/sotest: 7983
2020-07-10 09:32:49.633 9087-9087/calculations D/sotest: 6981
2020-07-10 09:32:50.636 9087-9087/calculations D/sotest: 5978
2020-07-10 09:32:51.640 9087-9087/calculations D/sotest: 4974
2020-07-10 09:32:52.643 9087-9087/calculations D/sotest: 3970
2020-07-10 09:32:53.647 9087-9087/calculations D/sotest: 2967
2020-07-10 09:32:54.650 9087-9087/calculations D/sotest: 1964
2020-07-10 09:32:55.653 9087-9087/calculations D/sotest: 961
2020-07-10 09:32:56.616 9087-9087/calculations D/sotest: Finish

一个可疑的陈述是这样的:

// Incorrect, this performs:
//   "every time the millisUntilFinished value is a multiple of 60,
//   decrement what most likely is a minute value."
if(l % 60 == 0) {
    min--;
}

因此看起来您正试图通过对毫秒值(也有错误)进行取模来维护分钟值。这是不正确的。

所以重点是简单的日志记录可以极大地帮助理解问题。

此外,从日志中您可以看到一个有趣的行为,即值的“漂移”。