2015年3月1日日曜日

【Android】【CountDownTimer】カウントダウンタイマーを、1つのボタンで開始、一時停止、リセットする。

現在タイマーを使ったアプリを作成している。

CountDownTimer というクラスが用意されているので、それを使えばタイマー作成には結構便利。

CountDownTimer は、そのままだと一時停止が使えないので、一時停止するにはちょっと工夫が必要だ。そのやり方については、こちらの記事を参考にさせて頂いた。

ただ、参考元のやり方そのままだと、ボタンが増えて画面がちょっと煩雑になってしまう。

ストップウォッチ感覚で直感的に操作できるようにしたいので、スタート、ストップは同じボタンにしたい。

Androidには標準で『トグルボタン』という、ON/OFFを切り替えられる便利なボタンがあるので、それを利用してタイマーを自分なりに再作成してみた。



トグルボタンは、AndroidStudioのパレットからドラッグ・アンド・ドロップでXML上に配置できる。


配置したトグルボタンは、JavaでOnCheckedChangeListener に関連付け、下記の様に、if (isChecked) - else で分けて、ON/OFF時の処理をそれぞれ記載する。

        toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                
                if (isChecked) {

                    // トグルボタンがONの際の処理を記述
                    
                } else {

                    // トグルボタンがOFFの際の処理を記述

                }
            }
        });

今回のタイマーでは、

[ON] タイマーをインスタンス化 → スタート
[OFF] タイマーをストップ

という処理を記述した。

ついでに setOnLongClickListener で、トグルボタンをロングクリックした時にタイマーをリセットするように設定した。
ロングクリックでリセットする際には、トグルボタンをOFFに変更する。そうしないと、タイマーはリセットされて動いていないのに、トグルがONのままという状況が発生してしまう。

以下、ソースコード全体

MainActivity.java
import android.os.CountDownTimer;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;

public class MainActivity extends ActionBarActivity {

    static MyCountDownTimer myCountDownTimer;

    // 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)); // ミリ秒 → 秒に変換して)残り時間を表示
        }

        // カウントダウン終了後の処理
        @Override
        public void onFinish() {
            toggleButton.setChecked(false); // toggleボタンをオフにする
        }
    }

    @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) {
                    String time = ((TextView) findViewById(R.id.textView)).getText().toString(); // テキストビューの文字列を取得して、timeに格納
                    myCountDownTimer = new MyCountDownTimer(Integer.parseInt(time) * 1000, 100); // timeをint型に変換した後、ミリ秒に変換。その時間をセットしたmyCountDownTimerをインスタンス化
                    myCountDownTimer.start(); // タイマーをスタート

                    // トグルOFF
                } else {
                    myCountDownTimer.cancel(); // タイマーをストップ
                }
            }
        });

        // トグルボタンをロングタップした時の処理
        ((ToggleButton)findViewById(R.id.toggleButton)).setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                myCountDownTimer.cancel(); // タイマーをストップ
                ((TextView)findViewById(R.id.textView)).setText("15"); // テキストビューに初期値をセット
                ((ToggleButton)findViewById(R.id.toggleButton)).setChecked(false); // toggleボタンをオフにする
                return true;
            }
        });
    }
}

activity_main.xml
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="15"
        android:id="@+id/textView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New ToggleButton"
        android:id="@+id/toggleButton"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

如何でしょうか。


(関連)
2015/3/10 【Android】【CountDownTimer】 0秒まで表示する (インターバルの挙動を調べてみる)
2015/3/10 【Android】【CountDownTimer】 一時停止の仕組みを改善する その①
2015/3/11 【Android】【CountDownTimer】 一時停止の仕組みを改善する その②

0 件のコメント:

コメントを投稿