安卓:倒计时器跳过最后一个onTick()!

52
public class SMH extends Activity {  

    public void onCreate(Bundle b) {  
        super.onCreate(b);  
        setContentView(R.layout.main);  

        TextView tv = (TextView) findViewById(R.id.tv);  

        new CountDownTimer(10000, 2000) {  
            public void onTick(long m) {  
               long sec = m/1000+1;  
               tv.append(sec+" seconds remain\n");  
            }  
            public void onFinish() {  
               tv.append("Done!");  
            }  
        }.start();  
   }

输出:
剩余10秒
剩余8秒
剩余6秒
剩余4秒
完成!

问题:

如何让它显示“剩余2秒”?已经经过了10秒,但最后一个onTick()没有发生。如果我将第二个参数从2000更改为1000,则会得到以下输出:

剩余10秒
剩余9秒
剩余8秒
剩余7秒
剩余6秒
剩余5秒
剩余4秒
剩余3秒
剩余2秒
完成!

所以你看,似乎跳过了最后一个onTick()调用。另外,XML文件基本上是默认的main.xml,TextView分配了id tv并将文本设置为空。


3
此问题已在 Oreo 中得到修复。 - Dewsworld
如果有人对向后兼容性感兴趣,虽然这个问题可能已经在Android 8中得到解决,但它仍然存在于Android 7中,并且我没有看到它在Android 5或6中按照OP的想法工作。 - Smartybartfast
12个回答

1
将几毫秒添加到计时器中,以便它有时间处理代码。我将+100添加到您的计时器长度,并且使用Math.ceil()来向上舍入结果,而不是加1。
另外...第一次tick是在2000毫秒后,因此除非您添加,否则不会出现“剩余10秒”条目。
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final TextView tv = (TextView) findViewById(R.id.tv);
    tv.setText("10 Seconds remain\n"); //displayed before the first tick.
    new CountDownTimer(10000+25, 1000) { //25 to account for processing time
        public void onTick(long m) {
            long sec = (long) Math.ceil(m / 2000 ); //round up, don't add 1
            tv.append(sec + " seconds remain\n");
        }
        public void onFinish() {
            tv.append("Done!");
        }
    }.start();
}

-1

您正在错误地计算剩余时间。回调函数返回任务完成所需的毫秒数。

public void onTick(long m) {  
    long sec = m/1000+1;  
    tv.append(sec+" seconds remain\n");  
}  

应该是

public void onTick(long m) {  
    long sec = m/1000;  
    tv.append(sec+" seconds remain\n");  
}

我自己从未使用过这个类,但看起来你不会在它启动的那一刻立即得到回调,这就是为什么它看起来像你错过了一个条目的原因。例如,计时器设置为10000毫秒,每个Tick花费1000毫秒,你将获得9个更新回调,而不是10个:9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000以及完成。


2
我加了那个 +1 是为了让输出更有意义。我在问题中的输出反映了倒计时实际剩余的时间,例如当它说“3 秒……2 秒……完成!”时,这意味着在“完成!”消息出现之前真正剩下了 2 秒。因此,如果我从 "long sec = m/1000" 中删去 "+1",那么文本将会说"2 秒……1 秒……完成!",即使当它说"1 秒"时,实际上还剩下 2 秒。这听起来有点混乱,但如果你尝试一下我的简短代码,你就会明白我在说什么。 - ProgrammingMakesMeQQ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接