Android中的倒计时时间

时间:2016-07-07 07:51:39

标签: java android countdowntimer

我正在开发Android应用,我需要:

1)倒计时时间从'x' minutes'1' minute,然后一旦到达1 minute,则按60 sec, 30 sec然后0计算。

我正在倒计时1分钟(60000)。

我的代码是:

public void countdowntimer(long timeinmillis, long countdowninterval){
        Log.d("hi","Iamhere 0" + timeinmillis/60000);
        new CountDownTimer(timeinmillis, countdowninterval) {

            public void onTick(long timeinmillis) {


                //Countdown the time in terms of minutes

                Log.d("hi","Iamhere 2" + timeinmillis);
                tv.setText(String.valueOf((timeinmillis)/60000) + "min");
                rootView.invalidate();
                if(timeinmillis <= 60000 && timeinmillis > 30000){
                   tv.setText(String.valueOf(60) + "sec");
                    rootView.invalidate();
                }else if(timeinmillis < 30000){
                    tv.setText(String.valueOf(30) + "sec");
                    rootView.invalidate();
                }
            }

            public void onFinish() {

            }
        }.start();
    }

日志是:

Iamhere0 4

Iamhere1 3

为什么我的第二个日志显示比第一个日志少1分钟?如何在1分钟后实现60秒,30秒倒计时?

预期输出为:

4 min

3 min

2 min

1 min -> 60sec

30sec

0

3 个答案:

答案 0 :(得分:1)

我花了一些时间来回答这个问题,这是我的瞻礼......但如果对任何人来说这仍然是有趣的话,这里还有另外一个解决方案。

我更喜欢使用System.currentTimeInMilli来管理计时器。当我开始它时,我计算结束时间然后在每个刻度线上,我计算显示的剩余时间。

此设计可防止使用任何增量/减量变量计时器发现延迟。为了保持这个类可重用,我在每个tick(本例中为100ms)上使用了Observer模式,Observable实例将发送给每个观察者。

public class RunnableTimer extends Observable implements Runnable {

    private final Handler handler;
    // Number of milliseconds to run before the end
    private Long delay;
    // Date in millis until the end of the timer
    private Long countDownEnd = null;
    //The calculate remaining time
    private long time;

    public RunnableTimer(Observer o){
        this.handler = new Handler();
        addObserver(o);
    }

    /**
     * Start the timer
     * @param delay : the number of milliseconds to run
     */
    public void start(Long delay){
        this.delay = delay;

        countDownEnd = System.currentTimeMillis() + delay;
        handler.postDelayed(this, 0);
    }

    @Override
    public void run() {
        time = countDownEnd - System.currentTimeMillis();

        if (time > 0)
            handler.postDelayed(this, 100); //Recalculate every 100ms, to keep some precision... can be more or less.
        else
            time = 0; //to prevent to show negative values

        sendUpdate();
    }


    public String toString(){
        long t = time / 1000;
        Log.d("time", "" + t);
        if(t >= 60){
            return String.format("%d min.", t/60);
        } if t <= 0){
            return "End";
        } else {
            return String.format("%d sec.", (t/30+1)*30);
        } 
    }

    /**
     * Send the instance to each observer.
     */
    private void sendUpdate(){
        setChanged();
        notifyObservers(toString());
    }
}

由此,您有一个使用系统时间计算剩余时间的计时器和创建所需模板的toString方法。

要使用它,只需使用您想要的观察者创建一个实例。

public class Test implements Observer {

    private RunnableTimer timer;

    public Test(){
        timer = new RunnableTimer(this);
        timer.start(65000) //65sec
    }

    @Override
    public void update(Observable observable, Object data) {
        if(data == timer){ //If the update comes from the timer
            Log.d("timer", timer.toString());
        }
    }
}

我必须清除我班级的一大部分,但这应该可以正常工作,因为这是更简单的版本。

编辑:在你的情况下,你的activity / fragment应该实现Observer,在更新中,我记录定时器,你应该把toString结果放到你的textfield中。

答案 1 :(得分:0)

尝试这样:

public class MyTimeCount extends CountDownTimer {
 private Button btn_code;

public MyTimeCount(long millisInFuture, long countDownInterval,Button btn) {
    super(millisInFuture, countDownInterval);
    btn_code=btn;
}

@Override
public void onFinish() {
    btn_code.setText("Reacquire");
    btn_code.setEnabled(true);
}
@Override
public void onTick(long millisUntilFinished){
    btn_code.setEnabled(false);
    btn_code.setText(millisUntilFinished /1000+"s");

}

}

答案 2 :(得分:-1)

使用AtomicInteger 维护线程状况

在First Condition中,显示以分钟为单位的时间

 if (min.get() > 1) {
                        mCount.setText(Integer.toString(min.get())+" min");
                        handler.postDelayed(this, 1000);
                        min.getAndDecrement();
                    }

AND

在最后一分钟,它进入第二个条件,以秒显示时间

else {

                    if(min.get()== 1) {
                        mCount.setText("60 Sec");
                        handler.postDelayed(this, 500);
                    }
                    else if(min.get() == 0){
                        mCount.setText("30 Sec");
                        handler.postDelayed(this, 500);
                    }
                    else
                        mCount.setText("0 Sec");
                        min.getAndDecrement();
                }

使用此...........

final TextView mCount = (TextView) findViewById(R.id.count);
        final Handler handler = new Handler();
        final AtomicInteger min = new AtomicInteger(4);
        final Runnable counter = new Runnable() {
            @Override
            public void run() {

                if (min.get() > 1) {
                    mCount.setText(Integer.toString(min.get())+" min");
                    handler.postDelayed(this, 1000);
                    min.getAndDecrement();
                } else {

                    if(min.get()== 1) {
                        mCount.setText("60 Sec");
                        handler.postDelayed(this, 500);
                    }
                    else if(min.get() == 0){
                        mCount.setText("30 Sec");
                        handler.postDelayed(this, 500);
                    }
                    else
                        mCount.setText("0 Sec");
                        min.getAndDecrement();
                }

            }
        };
        handler.postDelayed(counter, 0);

享受编码.....