Android:CountDownTimer 跳过最后一个 onTick()! [英] Android: CountDownTimer skips last onTick()!

查看:17
本文介绍了Android:CountDownTimer 跳过最后一个 onTick()!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码:

<块引用>

public class SMH extends Activity {公共无效 onCreate(Bundle b) {super.onCreate(b);setContentView(R.layout.main);TextView tv = (TextView) findViewById(R.id.tv);新倒计时(10000, 2000){公共无效 onTick(长米){长秒 = m/1000+1;tv.append(sec+" 剩余秒数
");}公共无效 onFinish() {tv.append("完成!");}}.开始();}

输出:
还剩 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 并且文本设置为".

解决方案

我不知道为什么最后一个滴答声不起作用,但您可以使用 Runable ,例如.

class MyCountDownTimer {私人长期millisInFuture;私人长countDownInterval;公共 MyCountDownTimer(长 pMillisInFuture,长 pCountDownInterval){this.millisInFuture = pMillisInFuture;this.countDownInterval = pCountDownInterval;}公共无效开始(){final Handler handler = new Handler();Log.v("状态", "开始");最终 Runnable 计数器 = new Runnable(){公共无效运行(){如果(millisInFuture <= 0){Log.v("状态", "完成");} 别的 {长秒 = millisInFuture/1000;Log.v("status", Long.toString(sec) + "剩余秒数");millisInFuture -= countDownInterval;handler.postDelayed(this, countDownInterval);}}};handler.postDelayed(counter, countDownInterval);}}

然后开始,

new MyCountDownTimer(10000, 2000).Start();

<小时>

编辑高飞的问题

你应该有一个变量来保存计数器状态 (boolean) .然后你可以写一个Stop()方法,比如Start().

编辑 2 高飞的问题

实际上停止计数器没有错误,但停止(恢复)后再次启动有错误.

我正在编写一个新的更新的完整代码,我刚刚尝试过,它正在运行.这是一个基本的计数器,通过开始和停止按钮在屏幕上显示时间.

计数器类

公共类 MyCountDownTimer {私人长期millisInFuture;私人长countDownInterval;私有布尔状态;公共 MyCountDownTimer(长 pMillisInFuture,长 pCountDownInterval){this.millisInFuture = pMillisInFuture;this.countDownInterval = pCountDownInterval;状态 = 假;初始化();}公共无效停止(){状态 = 假;}公共长 getCurrentTime() {返回millisInFuture;}公共无效开始(){状态 = 真;}公共无效初始化(){final Handler handler = new Handler();Log.v("状态", "开始");最终 Runnable 计数器 = new Runnable(){公共无效运行(){长秒 = millisInFuture/1000;如果(状态){如果(millisInFuture <= 0){Log.v("状态", "完成");} 别的 {Log.v("status", Long.toString(sec) + "剩余秒数");millisInFuture -= countDownInterval;handler.postDelayed(this, countDownInterval);}} 别的 {Log.v("status", Long.toString(sec) + " 剩余秒数,计时器已停止!");handler.postDelayed(this, countDownInterval);}}};handler.postDelayed(counter, countDownInterval);}}

活动课

公共类 CounterActivity 扩展 Activity {/** 在第一次创建活动时调用.*/TextView 时间文本;按钮开始但是;按钮停止但是;MyCountDownTimer mycounter;@覆盖public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);timeText = (TextView) findViewById(R.id.time);startBut = (Button) findViewById(R.id.start);stopBut = (Button) findViewById(R.id.stop);mycounter = new MyCountDownTimer(20000, 1000);刷新定时器();}public void StartTimer(View v) {Log.v("startbutton", "saymaya basladi");mycounter.Start();}public void StopTimer(View v) {Log.v("stopbutton", "durdu");mycounter.Stop();}public void RefreshTimer(){final Handler handler = new Handler();最终 Runnable 计数器 = new Runnable(){公共无效运行(){timeText.setText(Long.toString(mycounter.getCurrentTime()));handler.postDelayed(this, 100);}};handler.postDelayed(counter, 100);}}

ma​​in.xml

<TextView android:textAppearance="?android:attr/textAppearanceLarge"android:text="TextView" android:layout_height="wrap_content"android:layout_width="wrap_content"android:id="@+id/时间"></TextView><按钮 android:text="开始"android:id="@+id/开始"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="StartTimer"></按钮><按钮 android:text="停止"android:id="@+id/停止"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="StopTimer"></按钮></LinearLayout>

Code:

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
");  
            }  
            public void onFinish() {  
               tv.append("Done!");  
            }  
        }.start();  
   }

Output:
10 seconds remain
8 seconds remain
6 seconds remain
4 seconds remain
Done!

Problem:

How do I get it to show "2 seconds remain"? The time elapsed is indeed 10 seconds, but the last onTick() never happens. If I change the second parameter from 2000 to 1000, then this is the output:

10 seconds remain
9 seconds remain
8 seconds remain
7 seconds remain
6 seconds remain
5 seconds remain
4 seconds remain
3 seconds remain
2 seconds remain
Done!

So you see, it seems to be skipping that last onTick() call. And btw, the XML file is basically the default main.xml with the TextView assigned the id tv and the text set to "".

解决方案

I don't know why the last tick is not working but you can create your own timer with Runable , for example.

class MyCountDownTimer {
    private long millisInFuture;
    private long countDownInterval;
    public MyCountDownTimer(long pMillisInFuture, long pCountDownInterval) {
            this.millisInFuture = pMillisInFuture;
            this.countDownInterval = pCountDownInterval;
        }
    public void Start() 
    {
        final Handler handler = new Handler();
        Log.v("status", "starting");
        final Runnable counter = new Runnable(){

            public void run(){
                if(millisInFuture <= 0) {
                    Log.v("status", "done");
                } else {
                    long sec = millisInFuture/1000;
                    Log.v("status", Long.toString(sec) + " seconds remain");
                    millisInFuture -= countDownInterval;
                    handler.postDelayed(this, countDownInterval);
                }
            }
        };

        handler.postDelayed(counter, countDownInterval);
    }
}

and to start it,

new MyCountDownTimer(10000, 2000).Start();


EDIT FOR GOOFY'S QUESTION

you should have a variable to hold counter status (boolean) . then you can write a Stop() method like Start().

EDIT-2 FOR GOOFY'S QUESTION

actually there is no bug on stopping counter but there is a bug on start again after stop(resume).

I'm writing a new updated full code that I had just tried and it's working. It's a basic counter that show time on screen with start and stop button.

class for counter

public class MyCountDownTimer {
    private long millisInFuture;
    private long countDownInterval;
    private boolean status;
    public MyCountDownTimer(long pMillisInFuture, long pCountDownInterval) {
            this.millisInFuture = pMillisInFuture;
            this.countDownInterval = pCountDownInterval;
            status = false;
            Initialize();
    }

    public void Stop() {
        status = false;
    }

    public long getCurrentTime() {
        return millisInFuture;
    }

    public void Start() {
        status = true;
    }
    public void Initialize() 
    {
        final Handler handler = new Handler();
        Log.v("status", "starting");
        final Runnable counter = new Runnable(){

            public void run(){
                long sec = millisInFuture/1000;
                if(status) {
                    if(millisInFuture <= 0) {
                        Log.v("status", "done");
                    } else {
                        Log.v("status", Long.toString(sec) + " seconds remain");
                        millisInFuture -= countDownInterval;
                        handler.postDelayed(this, countDownInterval);
                    }
                } else {
                    Log.v("status", Long.toString(sec) + " seconds remain and timer has stopped!");
                    handler.postDelayed(this, countDownInterval);
                }
            }
        };

        handler.postDelayed(counter, countDownInterval);
    }
}

activity class

public class CounterActivity extends Activity {
    /** Called when the activity is first created. */
    TextView timeText;
    Button startBut;
    Button stopBut;
    MyCountDownTimer mycounter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        timeText = (TextView) findViewById(R.id.time);
        startBut = (Button) findViewById(R.id.start);
        stopBut = (Button) findViewById(R.id.stop);
        mycounter = new MyCountDownTimer(20000, 1000);
        RefreshTimer();
    }

    public void StartTimer(View v) {
        Log.v("startbutton", "saymaya basladi");
        mycounter.Start();
    }

    public void StopTimer(View v) {
        Log.v("stopbutton", "durdu");
        mycounter.Stop();
    }

    public void RefreshTimer() 
    {
        final Handler handler = new Handler();
        final Runnable counter = new Runnable(){

            public void run(){
                timeText.setText(Long.toString(mycounter.getCurrentTime()));
                handler.postDelayed(this, 100);
            }
        };

        handler.postDelayed(counter, 100);
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="1">
    <TextView android:textAppearance="?android:attr/textAppearanceLarge" 
              android:text="TextView" android:layout_height="wrap_content" 
              android:layout_width="wrap_content" 
              android:id="@+id/time">
    </TextView>
    <Button android:text="Start" 
            android:id="@+id/start" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:onClick="StartTimer">
    </Button>
    <Button android:text="Stop" 
            android:id="@+id/stop" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:onClick="StopTimer">
    </Button>
</LinearLayout>

这篇关于Android:CountDownTimer 跳过最后一个 onTick()!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆