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

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

问题描述

code:

 公共类SMH延伸活动{

    公共无效的onCreate(包B){
        super.onCreate(B);
        的setContentView(R.layout.main);

        TextView的电视=(TextView中)findViewById(R.id.tv);

        新CountDownTimer(10000,2000){
            公共无效onTick(长型m){
               长秒= M / 1000 + 1;
               tv.append(秒+秒保持\ N);
            }
            公共无效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与分配的ID的TextView中的电视的并设置为的文字。

解决方案

我不知道为什么最后一跳不工作,但你可以用的可运行的,例如。

 类MyCountDownTimer {
    专用长millisInFuture;
    专用长countDownInterval;
    公共MyCountDownTimer(长pMillisInFuture,长pCountDownInterval){
            this.millisInFuture = pMillisInFuture;
            this.countDownInterval = pCountDownInterval;
        }
    公共无效启动()
    {
        最终的处理程序处理程序=新的处理程序();
        Log.v(状态,出发);
        最终的可运行计数器=新的Runnable(){

            公共无效的run(){
                如果(millisInFuture&所述; = 0){
                    Log.v(状态,完成);
                } 其他 {
                    长秒= millisInFuture / 1000;
                    Log.v(状态,Long.toString(秒)+秒保持);
                    millisInFuture  -  = countDownInterval;
                    handler.postDelayed(这一点,countDownInterval);
                }
            }
        };

        handler.postDelayed(计数器,countDownInterval);
    }
}
 

和启动它,

 新MyCountDownTimer(10000,2000)。开始();
 


编辑愚蠢的问题

你应该有一个变量保存计数器状态(布尔)。那么你可以写一个stop()方法一样开始()。

修改-2愚蠢的问题

实际上没有对停止柜台没有错误但在启动一个错误停止(恢复)。

后再次

我写,我刚刚尝试了新的更新全code和它的工作。这是时间显示在屏幕上开始和停止按钮一个基本的计数器。

类柜台

 公共类MyCountDownTimer {
    专用长millisInFuture;
    专用长countDownInterval;
    私人布尔状态;
    公共MyCountDownTimer(长pMillisInFuture,长pCountDownInterval){
            this.millisInFuture = pMillisInFuture;
            this.countDownInterval = pCountDownInterval;
            状态= FALSE;
            初始化();
    }

    公共无效停止(){
        状态= FALSE;
    }

    众长getCurrentTime(){
        返回millisInFuture;
    }

    公共无效启动(){
        状态= TRUE;
    }
    公共无效初始化()
    {
        最终的处理程序处理程序=新的处理程序();
        Log.v(状态,出发);
        最终的可运行计数器=新的Runnable(){

            公共无效的run(){
                长秒= millisInFuture / 1000;
                如果(状态){
                    如果(millisInFuture&所述; = 0){
                        Log.v(状态,完成);
                    } 其他 {
                        Log.v(状态,Long.toString(秒)+秒保持);
                        millisInFuture  -  = countDownInterval;
                        handler.postDelayed(这一点,countDownInterval);
                    }
                } 其他 {
                    Log.v(状态,Long.toString(秒)+秒保持和定时器已经停了!);
                    handler.postDelayed(这一点,countDownInterval);
                }
            }
        };

        handler.postDelayed(计数器,countDownInterval);
    }
}
 

活动类

 公共类CounterActivity延伸活动{
    / **第一次创建活动时调用。 * /
    TextView的timeText;
    按钮startBut;
    按钮stopBut;
    MyCountDownTimer mycounter;

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
        timeText =(TextView中)findViewById(R.id.time);
        startBut =(按钮)findViewById(R.id.start);
        stopBut =(按钮)findViewById(R.id.stop);
        mycounter =新MyCountDownTimer(20000,1000);
        RefreshTimer();
    }

    公共无效StartTimer(视图v){
        Log.v(startbutton,saymaya basladi);
        mycounter.Start();
    }

    公共无效StopTimer(视图v){
        Log.v(STOPBUTTON,durdu);
        mycounter.Stop();
    }

    公共无效RefreshTimer()
    {
        最终的处理程序处理程序=新的处理程序();
        最终的可运行计数器=新的Runnable(){

            公共无效的run(){
                timeText.setText(Long.toString(mycounter.getCurrentTime()));
                handler.postDelayed(此,100);
            }
        };

        handler.postDelayed(计数器,100);
    }
}
 

的main.xml

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:方向=垂直
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:weightSum =1>
    < TextView的Andr​​oid的:机器人:ATTR / textAppearanceLargetextAppearance =
              机器人:文本=TextView的机器人:layout_height =WRAP_CONTENT
              机器人:layout_width =WRAP_CONTENT
              机器人:ID =@ + ID /时间>
    < / TextView的>
    <按钮的android:文本=开始
            机器人:ID =@ + ID /启动
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:的onClick =StartTimer>
    < /按钮>
    <按钮的android:文本=停止
            机器人:ID =@ + ID /停止
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:的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\n");  
            }  
            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>

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

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