改善策② 残り時間(millisUntilFinished)を、インターバル毎に記録する。
millisUntilFinishedは、CountDownTimerクラスのonTick()メソッドで使用される変数で、残り時間(ミリ秒)の値が格納されています。これを、一時停止時に使用出来れば良いのですが、この変数はonTick()メソッドの範囲外では使えません。
そこで、あらかじめ定義した別の変数(countMillis)にmillisUntilFinishedの値をコピーする処理を、onTick()メソッドの中に追加します。これで、インターバル時間毎に、残り時間がcountMillisに記録されます。
public void onTick(long millisUntilFinished) {
textView.setText(String.valueOf(millisUntilFinished / 1000)); // ミリ秒→秒に変換して)残り時間を表示
countMillis = millisUntilFinished; // 残り時間をcountMillisに代入
}
カウントダウンタイマーを再スタートする際に、countMillisを残り時間(millisInFuture)にセットしてインスタンス化すれば、ミリ秒を切り捨てずに残り時間からスタートできます。(ただし、正確性は残り時間(millisUntilFinished)を記録する頻度、つまりインターバル時間にも依存します。)
// トグルON
if (isChecked) {
myCountDownTimer = new MyCountDownTimer(countMillis, 100); //countMillisを残り時間にセット
myCountDownTimer.start(); // タイマーをスタート
// トグルOFF
} else {
myCountDownTimer.cancel(); // タイマーをストップ
}
なお、countMillisは、変数を定義する際に忘れずに初期化(初期値をセット)しておきます。そうしなければ、最初にタイマーをスタートする際に、countMillisには値が何も入っていないのでエラーに成ってしまいます。
また、リセットの処理にも、countMillisに初期値をセットする処理を追加します。
思いついた処理は昨日の対応策①と合わせてこの2つです。
個人的には今回紹介した②の方が、強引さが無くて好きです。
参考までに、Javaのコード全文を掲載します。
(XMLは、『【Android】【CountDownTimer】カウントダウンタイマーを、1つのボタンで開始、一時停止、リセットする。』と同じ)
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;
public class MainActivity extends ActionBarActivity {
private static MyCountDownTimer myCountDownTimer;
private static long countMillis = 15000; // カウントダウンの残り時間(初期値)
// CountDownTimerクラスを継承して、MyCountDownTimerを定義
class MyCountDownTimer extends CountDownTimer {
// 秒を表示するテキストビュー、トグルボタンのビューを取得
TextView textView = (TextView)findViewById(R.id.textView);
ToggleButton toggleButton = (ToggleButton)findViewById(R.id.toggleButton);
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
// カウントダウン処理
@Override
public void onTick(long millisUntilFinished) {
textView.setText(String.valueOf(millisUntilFinished / 1000)); // ミリ秒→秒に変換して)残り時間を表示
countMillis = millisUntilFinished; // 残り時間をcountMillisに代入
}
// カウントダウン終了後の処理
@Override
public void onFinish() {
toggleButton.setChecked(false); // toggleボタンをオフにする
textView.setText("0");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// トグルボタンをタップした時の処理
((ToggleButton)findViewById(R.id.toggleButton)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// トグルON
if (isChecked) {
myCountDownTimer = new MyCountDownTimer(countMillis, 100); //countMillisを残り時間にセット
myCountDownTimer.start(); // タイマーをスタート
// トグルOFF
} else {
myCountDownTimer.cancel(); // タイマーをストップ
}
}
});
// トグルボタンをロングタップした時の処理
((ToggleButton)findViewById(R.id.toggleButton)).setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
myCountDownTimer.cancel(); // タイマーをストップ
countMillis = 15000; // カウントダウン時間を初期値にリセット
((TextView)findViewById(R.id.textView)).setText(String.valueOf(countMillis / 1000)); // テキストビューに初期値をセット
((ToggleButton)findViewById(R.id.toggleButton)).setChecked(false); // toggleボタンをオフにする
return true;
}
});
}
}
(関連)
【Android】【CountDownTimer】カウントダウンタイマーを、1つのボタンで開始、一時停止、リセットする。
【Android】【CountDownTimer】 0秒まで表示する (インターバルの挙動を調べてみる)
【Android】【CountDownTimer】 一時停止の仕組みを改善する その①





















