2015年3月11日水曜日

【Android】【CountDownTimer】 一時停止の仕組みを改善する その②

その①に引き続き、一時停止の仕組みについて検討します。

改善策② 残り時間(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】 一時停止の仕組みを改善する その①

0 件のコメント:

コメントを投稿