2011-11-29 295 views
14

我開發了一個倒數計時器,我不確定如何暫停和恢復定時器的textview正在點擊。點擊開始,然後再次點擊以暫停並恢復,再次點擊計時器的文本視圖。Android:如何暫停和恢復倒數計時器?

這是我的代碼:

Timer = (TextView) this.findViewById(R.id.time); //TIMER 
    Timer.setOnClickListener(TimerClickListener); 
    counter = new MyCount(600000, 1000); 
}//end of create 

private OnClickListener TimerClickListener = new OnClickListener() { 
    public void onClick(View v) { 
     updateTimeTask(); 
    } 

    private void updateTimeTask() { 
     if (decision == 0) { 
      counter.start(); 
      decision = 1; 
     } else if (decision == 2) { 
      counter.onResume1(); 
      decision = 1; 
     } else { 
      counter.onPause1(); 
      decision = 2; 
     }//end if 
    } 

    ; 
}; 

class MyCount extends CountDownTimer { 
    public MyCount(long millisInFuture, long countDownInterval) { 
     super(millisInFuture, countDownInterval); 
    }//MyCount 

    public void onResume1() { 
     onResume(); 
    } 

    public void onPause1() { 
     onPause(); 
    } 

    public void onFinish() { 
     Timer.setText("00:00"); 
     p1++; 
     if (p1 <= 4) { 
      TextView PScore = (TextView) findViewById(R.id.pscore); 
      PScore.setText(p1 + ""); 
     }//end if 
    }//finish 

    public void onTick(long millisUntilFinished) { 
     Integer milisec = new Integer(new Double(millisUntilFinished).intValue()); 
     Integer cd_secs = milisec/1000; 

     Integer minutes = (cd_secs % 3600)/60; 
     Integer seconds = (cd_secs % 3600) % 60; 

     Timer.setText(String.format("%02d", minutes) + ":" 
       + String.format("%02d", seconds)); 
     ///long timeLeft = millisUntilFinished/1000; 
     /}//on tick 
}//class MyCount 

protected void onResume() { 
    super.onResume(); 
    //handler.removeCallbacks(updateTimeTask); 
    //handler.postDelayed(updateTimeTask, 1000); 
}//onResume 

@Override 
protected void onPause() { 
    super.onPause(); 
    //do stuff 
}//onPause 
+0

這將surelyhelp你 http://stackoverflow.com/questions/3510433/countdown-timer-required-on-android –

+0

的http://開發商。 android.com/reference/android/os/CountDownTimer.html –

+0

我需要使用crono來暫停和恢復嗎? – Mineko

回答

21
/* 
* Copyright (C) 2010 Andrew Gainer 
* 
* 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. 
*/ 

// Adapted from Android's CountDownTimer class 

package com.cycleindex.multitimer; 

import android.os.Handler; 
import android.os.Message; 
import android.os.SystemClock; 

/** 
* Schedule a countdown until a time in the future, with 
* regular notifications on intervals along the way. 
* 
    * 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 CountDownTimerWithPause { 

    /** 
    * Millis since boot when alarm should stop. 
    */ 
    private long mStopTimeInFuture; 

    /** 
    * Real time remaining until timer completes 
    */ 
    private long mMillisInFuture; 

    /** 
    * Total time on timer at start 
    */ 
    private final long mTotalCountdown; 

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

    /** 
    * The time remaining on the timer when it was paused, if it is currently paused; 0 otherwise. 
    */ 
    private long mPauseTimeRemaining; 

    /** 
    * True if timer was started running, false if not. 
    */ 
    private boolean mRunAtStart; 

    /** 
    * @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 in millis at which to execute 
    * {@link #onTick(millisUntilFinished)} callbacks 
    * @param runAtStart True if timer should start running, false if not 
    */ 
    public CountDownTimerWithPause(long millisOnTimer, long countDownInterval, boolean runAtStart) { 
     mMillisInFuture = millisOnTimer; 
     mTotalCountdown = mMillisInFuture; 
     mCountdownInterval = countDownInterval; 
     mRunAtStart = runAtStart; 
    } 

    /** 
    * Cancel the countdown and clears all remaining messages 
    */ 
    public final void cancel() { 
     mHandler.removeMessages(MSG); 
    } 

    /** 
    * Create the timer object. 
    */ 
    public synchronized final CountDownTimerWithPause create() { 
     if (mMillisInFuture <= 0) { 
      onFinish(); 
     } else { 
      mPauseTimeRemaining = mMillisInFuture; 
     } 

     if (mRunAtStart) { 
      resume(); 
     } 

     return this; 
    } 

    /** 
    * Pauses the counter. 
    */ 
    public void pause() { 
    if (isRunning()) { 
     mPauseTimeRemaining = timeLeft(); 
     cancel(); 
    } 
    } 

    /** 
    * Resumes the counter. 
    */ 
    public void resume() { 
    if (isPaused()) { 
     mMillisInFuture = mPauseTimeRemaining; 
     mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture; 
      mHandler.sendMessage(mHandler.obtainMessage(MSG)); 
     mPauseTimeRemaining = 0; 
    } 
    } 

    /** 
    * Tests whether the timer is paused. 
    * @return true if the timer is currently paused, false otherwise. 
    */ 
    public boolean isPaused() { 
    return (mPauseTimeRemaining > 0); 
    } 

    /** 
    * Tests whether the timer is running. (Performs logical negation on {@link #isPaused()}) 
    * @return true if the timer is currently running, false otherwise. 
    */ 
    public boolean isRunning() { 
    return (! isPaused()); 
    } 

    /** 
    * Returns the number of milliseconds remaining until the timer is finished 
    * @return number of milliseconds remaining until the timer is finished 
    */ 
    public long timeLeft() { 
    long millisUntilFinished; 
    if (isPaused()) { 
     millisUntilFinished = mPauseTimeRemaining; 
    } else { 
     millisUntilFinished = mStopTimeInFuture - SystemClock.elapsedRealtime(); 
     if (millisUntilFinished < 0) millisUntilFinished = 0; 
    } 
    return millisUntilFinished; 
    } 

    /** 
    * Returns the number of milliseconds in total that the timer was set to run 
    * @return number of milliseconds timer was set to run 
    */ 
    public long totalCountdown() { 
    return mTotalCountdown; 
    } 

    /** 
    * Returns the number of milliseconds that have elapsed on the timer. 
    * @return the number of milliseconds that have elapsed on the timer. 
    */ 
    public long timePassed() { 
    return mTotalCountdown - timeLeft(); 
    } 

    /** 
    * Returns true if the timer has been started, false otherwise. 
    * @return true if the timer has been started, false otherwise. 
    */ 
    public boolean hasBeenStarted() { 
    return (mPauseTimeRemaining <= mMillisInFuture); 
    } 

    /** 
    * 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 (CountDownTimerWithPause.this) { 
       long millisLeft = timeLeft(); 

       if (millisLeft <= 0) { 
        cancel(); 
        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 = mCountdownInterval - (SystemClock.elapsedRealtime() - lastTickStart); 

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

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

來源:This Gist.

+0

未找到:@其中是接受的原因 –

+0

因爲您可以看到前一段時間添加的鏈接,並且可以陳述 – hexin

+0

提供了一些其他鏈接,或者您可以粘貼您的代碼。 –

7

那麼有沒有API來暫停或恢復它。你應該做的是計時器cancel()並將剩餘時間存儲在變量中。當再次按下繼續按鈕時,用變量的值重新啓動計時器。


你知道Chronometers可能是你感興趣的。

+0

嗯,我需要使用savedInstanceState存儲剩餘時間?或者我會使用這個:/// long timeLeft = millisUntilFinished/1000;從我的代碼?謝謝 – Mineko

+0

如果你知道你的Activity包含了定時器[已銷燬並重新創建,那麼你必須將定時器值存儲在'savedInstanceState'](http://stackoverflow.com/a/151940/68805) – Reno

+0

Sorry Im新的android編程。我將如何使用savedInstanceState存儲計時器值? – Mineko

8

一個很好的和簡單的方法來創建你的CountDownTimer一個暫停/恢復如下:爲您創造定時器開始暫停簡歷一個單獨的方法:

public void timerStart(long timeLengthMilli) { 
     timer = new CountDownTimer(timeLengthMilli, 1000) { 

      @Override 
      public void onTick(long milliTillFinish) { 
       milliLeft=milliTillFinish; 
       min = (milliTillFinish/(1000*60)); 
       sec = ((milliTillFinish/1000)-min*60); 
       clock.setText(Long.toString(min)+":"+Long.toString(sec)); 
       Log.i("Tick", "Tock"); 
      } 
     } 
     timer.start(); 

timerStart有一個長參數,因爲它將被resume()方法如下。請記住將您的milliTillFinished(以上顯示爲milliLeft),以便您可以通過您的簡歷()方法發送它。暫停和恢復分別如下方法:

public void timerPause() { 
     timer.cancel(); 
    } 

    private void timerResume() { 
     Log.i("min", Long.toString(min)); 
     Log.i("Sec", Long.toString(sec)); 
     timerStart(milliLeft); 
    } 

這裏是FYI按鈕的代碼:

startPause.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       if(startPause.getText().equals("Start")){ 
        Log.i("Started", startPause.getText().toString()); 
        startPause.setText("Pause"); 
        timerStart(15*1000); 
       } else if (startPause.getText().equals("Pause")){ 
        Log.i("Paused", startPause.getText().toString()); 
        startPause.setText("Resume"); 
        timerPause(); 
       } else if (startPause.getText().equals("Resume")){ 
        startPause.setText("Pause"); 
        timerResume(); 
       } 
1

您可以嘗試使用Hourglass

Hourglass hourglass = new Hourglass(50000, 1000) { 
     @Override 
     public void onTimerTick(long timeRemaining) { 
      // Update UI 
      Toast.show(MainActivity.this, String.valueOf(timeRemaining), Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public void onTimerFinish() { 
      // Timer finished 
      Toast.show(MainActivity.this, "Timer finished", Toast.LENGTH_SHORT).show(); 


     } 
    }; 

使用hourglass.startTimer();啓動定時器。

它有輔助方法,允許暫停和恢復定時器。

hourglass.pauseTimer(); 

hourglass.resumeTimer(); 
+0

這很好。 – piddler