2012-06-27 214 views
1

我想在倒数计时器完成时用新时间重新启动倒数计时器。我给下面的代码:用新时间重新启动倒数计时器android

futureInMillis = newTime(); 

      CountDownTimer remainingTimeCounter = new CountDownTimer(futureInMillis, 1000) { 

      public void onTick(long millisUntilFinished) { 
       remainingTime = calculateRemainingTime(millisUntilFinished/1000); 
       runOnUiThread(updateTime); 
      } 

      public void onFinish() { 
       // TODO: restart counter 
       cancel(); 
       futureInMillis = newTime(); 
//    remainingTimeCounter = null; 
       this.start(); 
      } 
     }.start(); 
+0

有什么问题?你有问题吗? – thepoosh

+0

我想在计数器onFinish()调用时重新启动countdownTimer。此代码重新启动计时器,但不会更改时间。 – Nuraiz

回答

5

我们应该知道什么newTime()做的,你不必调用该方法cancel(),因为计时器是在onFinish()方法,这意味着,计时器数完下:

CountDownTimer remainingTimeCounter = new CountDownTimer(futureInMillis, 1000) { 

      public void onTick(long millisUntilFinished) { 
       remainingTime = calculateRemainingTime(millisUntilFinished/1000); 
       runOnUiThread(updateTime); 
      } 

      public void onFinish() { 
       // TODO: restart counter 
       //cancel(); // there is no need the call the cancel() method here 
       futureInMillis = newTime(); 
//    remainingTimeCounter = null; 
       this.start(); 
      } 
     }.start(); 

编辑:

存在在类CountDownTimer没有attribut才能使用改变futureInMillis, 如果你想使用它,你应该使用两个CountDownTimer;你应该创建两个类,每个类都有一个定时器和一个属性futureInMillis,然后当第一个类的定时器完成时,实例化第二个类,传递futureInMillis给它,并启动她的定时器,反之亦然。

**EDIT 2 :** 

或者干脆编辑从源代码的Android类CountDownTimer的代码源,并添加getter和setter方法为attributs futureInMillis这样的:

/* 
* Copyright (C) 2008 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

//add your package declaration here 

import android.util.Log; 

/** 
* Schedule a countdown until a time in the future, with 
* regular notifications on intervals along the way. 
* 
* Example of showing a 30 second countdown in a text field: 
* 
* <pre class="prettyprint"> 
* new CountdownTimer(30000, 1000) { 
* 
*  public void onTick(long millisUntilFinished) { 
*   mTextField.setText("seconds remaining: " + millisUntilFinished/1000); 
*  } 
* 
*  public void onFinish() { 
*   mTextField.setText("done!"); 
*  } 
* }.start(); 
* </pre> 
* 
* The calls to {@link #onTick(long)} are synchronized to this object so that 
* one call to {@link #onTick(long)} won't ever occur before the previous 
* callback is complete. This is only relevant when the implementation of 
* {@link #onTick(long)} takes an amount of time to execute that is significant 
* compared to the countdown interval. 
*/ 
public abstract class MyCountDownTimer { 

    /** 
    * Millis since epoch when alarm should stop. 
    */ 
    private long mMillisInFuture; 

    /** 
    * The interval in millis that the user receives callbacks 
    */ 
    private long mCountdownInterval; 

    private long mStopTimeInFuture; 



    /** 
    * @param millisInFuture The number of millis in the future from the call 
    * to {@link #start()} until the countdown is done and {@link #onFinish()} 
    * is called. 
    * @param countDownInterval The interval along the way to receive 
    * {@link #onTick(long)} callbacks. 
    */ 
    public MyCountDownTimer(long millisInFuture, long countDownInterval) { 
     mMillisInFuture = millisInFuture; 
     mCountdownInterval = countDownInterval; 
    } 

    public void setMillisInFuture(long millisInFuture) { 
     this.mMillisInFuture = millisInFuture; 
    } 

    public void setCountdownInterval(long countdownInterval) { 
     this.mCountdownInterval = countDownInterval; 
    } 

    /** 
    * Cancel the countdown. 
    */ 
    public final void cancel() { 
     mHandler.removeMessages(MSG); 
    } 

    /** 
    * Start the countdown. 
    */ 
    public synchronized final MyCountDownTimer start() { 
     if (mMillisInFuture <= 0) { 
      onFinish(); 
      return this; 
     } 
     mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; 
     mHandler.sendMessage(mHandler.obtainMessage(MSG)); 
     return this; 
    } 


    /** 
    * Callback fired on regular interval. 
    * @param millisUntilFinished The amount of time until finished. 
    */ 
    public abstract void onTick(long millisUntilFinished); 

    /** 
    * Callback fired when the time is up. 
    */ 
    public abstract void onFinish(); 


    private static final int MSG = 1; 


    // handles counting down 
    private Handler mHandler = new Handler() { 

     @Override 
     public void handleMessage(Message msg) { 

      synchronized (MyCountDownTimer.this) { 
       final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); 

       if (millisLeft <= 0) { 
        onFinish(); 
       } else if (millisLeft < mCountdownInterval) { 
        // no tick, just delay until done 
        sendMessageDelayed(obtainMessage(MSG), millisLeft); 
       } else { 
        long lastTickStart = SystemClock.elapsedRealtime(); 
        onTick(millisLeft); 

        // take into account user's onTick taking time to execute 
        long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime(); 

        // special case: user's onTick took more than interval to 
        // complete, skip to next interval 
        while (delay < 0) delay += mCountdownInterval; 

        sendMessageDelayed(obtainMessage(MSG), delay); 
       } 
      } 
     } 
    }; 
} 

,然后你可以很容易地改变millisInFuture这样:

MyCountDownTimer remainingTimeCounter = new MyCountDownTimer(futureInMillis, 1000) { 

       public void onTick(long millisUntilFinished) { 
        remainingTime = calculateRemainingTime(millisUntilFinished/1000); 
        runOnUiThread(updateTime); 
       } 

       public void onFinish() { 
        // TODO: restart counter with millisInFuture = 4000 (4 seconds) 
        //cancel(); // there is no need the call the cancel() method here 

        this.setMillisInFuture(4000); // here we change the millisInFuture of our timer 
        this.start(); 
       } 
      }.start(); 
+0

感谢您的回答。它适用于硬编码的millisInFuture,但如果我调用我的方法futureInMillis = newTime();发生StackOverflowException。 – Nuraiz

+1

添加您的代码为您的类newTime(),所以我们可以理解我们应该怎么做才能让它工作:) – Houcine

+0

完美的解决方案..! –