LoginSignup
5
3

More than 3 years have passed since last update.

かんたん色々な機能?を持つタイマー

2019年12月10日に書かないといけなかったのですが年を越してしまいました。

では、今回紹介しますは↓

「タイマー」アプリ!!!

スタート、ストップ、リセット以外に簡単な機能(すごくいらない機能)を付け加えて見ました。

画像完成イメージです。↓
Photo_20-01-08-16-38-02.318.png

必要なもの

・PC

・Android Studio (主は3.0.1)

アプリ作成-1 準備

いつもどおりに、プロジェクトを作成していきます。

・APIレベルは26(android8.0)で作ってます。

・Activityの種類はEmptyを指定してます。

アプリ作成-2 画面作り

画面にボタンを配置していきましょう。

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
〜省略〜
>


    <TextView
        android:id="@+id/text_view_countdown"
        android:layout_width="395dp"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginEnd="7dp"
        android:layout_marginStart="7dp"
        android:gravity="center"
        android:text="@string/_00_00"
        android:textColor="@android:color/black"
        android:textSize="40sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.48"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.280" />

    <Button
        android:id="@+id/button_start_pause"
        android:layout_width="395dp"
        android:layout_height="43dp"
        android:layout_below="@+id/text_view_countdown"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:text="@string/start"
        app:layout_constraintBottom_toTopOf="@+id/button_reset"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_view_countdown" />

    <Button
        android:id="@+id/button_reset"
        android:layout_width="395dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button_start_pause"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:text="@string/reset"
        android:visibility="invisible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_start_pause"
        tools:visibility="visible" />
    <Button
        android:id="@+id/button_pause"
        android:layout_width="395dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button_reset"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:text="@string/pause"
        android:visibility="invisible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_reset"
        tools:visibility="visible" />

    <Button
        android:id="@+id/button_skip"
        android:layout_width="395dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button_pause"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:text="@string/skip"
        android:visibility="invisible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_pause"
        tools:visibility="visible" />

    <Button
        android:id="@+id/button_return"
        android:layout_width="395dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button_skip"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:text="@string/not_return"
        android:visibility="invisible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_skip"
        tools:visibility="visible" />

</android.support.constraint.ConstraintLayout>

はいViewでございます。(android.support.constraint.ConstraintLayoutはそれぞれ個人により異なります。)

        android:text="@string/pause"

とかでエラーを起こされると思いますので、今度はstrings.xmlを追記していきます。

<resources>
    <string name="app_name">timer</string>
    <string name="_00_00">00:00</string>
    <string name="start">スタート</string>
    <string name="reset">リセット</string>
    <string name="stop">STOP</string>
    <string name="pause">ザ・ワールド</string>
    <string name="skip">キング・クリムゾン</string>
    <string name="not_return">GER</string>
</resources>

はい、pause、skipボタンの名前は各自適当にあてましょう

これで画面は表示できる状態になるかとおもいます。

アプリ作成-3 タイマーの処理1

MainActivity.javaに画面にあるそれぞれのボタンを押下時の処理を書いていきます!!

最初にフィールド変数を定義します。

public class MainActivity extends AppCompatActivity {

    //タイマー設定 単位 ミリ秒
    private static final long START_TIME_IN_MILLIS = 180000;

    //一時停止設定 単位 ミリ秒
    private static final long PAUSE_IN_MILLIS = 7000;

    //スキップ設定 単位 ミリ秒
    private static final long SKIP_TIME_IN_MILLIS = 5000;

    //カウントダウンタイマー
    private TextView mTextCountDown;
    //ボタン
    private Button mButtonStart;    //スタート
    private Button mButtonReset;    //リセット
    private Button mButtonPause;    //一時停止
    private Button mButtonSkip;     //スキップ
    private Button mButtonReturn;   //戻る

    //CountDownTimerクラス
    private CountDownTimer mCountDownTimer;
    //CallTimeクラス
    private boolean mTimerRunning;

    private long mTime = START_TIME_IN_MILLIS;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    省略

ここでタイマーの初期時間、一時停止の停止時間、スキップの飛ばす時間を定義します。

アプリ作成-3 タイマーの処理2

それぞれのボタン押下時の挙動を先に書きます!

//〜上にprotected void onCreate(Bundle savedInstanceState)のあれがあります。〜

    //タイマー再開の処理
    private void startTimer() {
        mCountDownTimer = new CountDownTimer(mTime,1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTime = millisUntilFinished;
                updateCountDownText();
            }

            @Override
            public void onFinish() {
                mTimerRunning = false;  //タイマー停止中
                mTime = START_TIME_IN_MILLIS;
                mButtonStart.setText("スタート");
                mButtonReset.setVisibility(View.INVISIBLE);
                mButtonPause.setVisibility(View.INVISIBLE);
                mButtonSkip.setVisibility(View.INVISIBLE);
                mButtonReturn.setVisibility(View.INVISIBLE);
            }
        }.start();

        mTimerRunning = true;   //タイマー作動中
        mButtonStart.setText("一時停止");
        mButtonReset.setVisibility(View.VISIBLE);
        mButtonPause.setVisibility(View.VISIBLE);
        mButtonSkip.setVisibility(View.VISIBLE);
        mButtonReturn.setVisibility(View.VISIBLE);

    }

    //タイマー一時停止の処理
    private void pauseTimer() {
        mCountDownTimer.cancel();
        mTimerRunning = false;
        mButtonStart.setText("スタート");
        mButtonReset.setVisibility(View.VISIBLE);
    }

    //タイマーリセットの処理
    private void resetTimer() {
        mTime = START_TIME_IN_MILLIS;
        updateCountDownText();
        mCountDownTimer.cancel();
        mButtonStart.setText("スタート");
        mTimerRunning = false;
        mButtonStart.setVisibility(View.VISIBLE);
        mButtonReset.setVisibility(View.INVISIBLE);
        mButtonPause.setVisibility(View.INVISIBLE);
        mButtonSkip.setVisibility(View.INVISIBLE);
        mButtonReturn.setVisibility(View.INVISIBLE);

    }

    //タイマー表示
    private void updateCountDownText() {
        int minutes = (int)(mTime / 1000) / 60;
        int seconds = (int)(mTime / 1000) % 60;

        String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d",minutes,seconds);
        mTextCountDown.setText(timeFormatted);
    }

これでボタンの押したときにそれぞれ動く処理を書きました。

基本的には「タイマーを止める」を応用したやり方でスキップや停止を実現している感じです。

アプリ作成-3 タイマーの処理3

ボタンにonClickを実装して押下したときに動くようにします

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextCountDown  = findViewById(R.id.text_view_countdown);
        mButtonStart    = findViewById(R.id.button_start_pause);
        mButtonReset    = findViewById(R.id.button_reset);
        mButtonPause    = findViewById(R.id.button_pause);
        mButtonSkip     = findViewById(R.id.button_skip);
        mButtonReturn   = findViewById(R.id.button_return);

        //スタートボタン
        mButtonStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //タイマーの状態を取得
                if (mTimerRunning) {
                    //動いてるなら停止
                    pauseTimer();
                } else {
                    startTimer();
                }
            }
        });

        //リセットボタン
        mButtonReset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //タイマーのリセット
                resetTimer();
            }
        });

        //一時停止ボタン
        mButtonPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //タイマーを停止
                mCountDownTimer.cancel();
                //7秒後実行
                new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //タイマーの再開
                        startTimer();
                    }
                }, PAUSE_IN_MILLIS);

            }
        });

        //スキップボタン
        mButtonSkip.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //タイマーを停止
                mCountDownTimer.cancel();
                int futureTime = (int)(mTime - SKIP_TIME_IN_MILLIS);
                //残り時間が0以上あるならスキップ
                if (futureTime >= 0) {
                    mTime = futureTime;
                    int minutes = (futureTime / 1000) / 60;
                    int seconds = (futureTime / 1000) % 60;
                    String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d",minutes,seconds);
                    mTextCountDown.setText(timeFormatted);
                //残り時間0になるならリセット
                } else {
                    resetTimer();
                }
                startTimer();
            }
        });

        //戻るボタン
        mButtonReturn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resetTimer();
                startTimer();

            }
        });

        updateCountDownText();
    }

ここまで書けば、タイマーとして動かせます。
実際にコンパイルして実機で動かしてみてください。

Photo_20-01-08-16-38-00.994.png


あとがき

読んでいただきありがとうございます。

ほとんどソースのベタ貼りですが、CountDownTimerの使っただけですのであんまり書くことがなかったです。

(他にも色々つけたかったのですが、時間のご都合上ここまでにさせていただきます。ほぼ1ヶ月も期限超えてますしおすし)

最初はカウンターアプリにしようかと思ってました。(ボタン押すたびにカウントアップしてアニメーションで上から下にデュランダルがぶっ刺さる風のやつ)

To Be Continued

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3