0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

flutter_hooksでストップウォッチを作る

Posted at

flutter_hooksのHookWidgetで状態管理を行い、ストップウォッチを作ってみた!

今回使うパッケージ
https://pub.dev/packages/flutter_hooks

これがソースコード

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

class StopWatch extends HookWidget {
  const StopWatch({super.key});

  @override
  Widget build(BuildContext context) {
    final timer = useState<Stopwatch?>(null);
    final elapsedTime = useState<Duration>(Duration.zero);

    useEffect(() {
      Timer.periodic(const Duration(seconds: 1), (Timer t) {
        if (timer.value?.isRunning ?? false) {
          elapsedTime.value = elapsedTime.value + const Duration(seconds: 1);
        }
      });
      return null; // useEffectのクリーンアップは不要なのでnullを返す
    }, []);

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              elapsedTime.value.toString().split('.').first.padLeft(8, "0"),
              style: TextStyle(fontSize: 24),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    if (timer.value == null) {
                      timer.value = Stopwatch()..start();
                    } else {
                      timer.value?.start();
                    }
                  },
                  child: Text("開始"),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    timer.value?.stop();
                  },
                  child: Text("一時停止"),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: () {
                    timer.value?.stop();
                    elapsedTime.value = Duration.zero;
                    timer.value = null;
                  },
                  child: const Text("完了"),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }
}

機能について解説

Dartの標準機能役割について解説

final timer = useState<Stopwatch?>(null);

この行では、現在のStopwatchインスタンスを保持するためのuseStateを使用しています。初期値はnullで、これはストップウォッチが開始されるまでのデフォルトの状態を示しています。

final elapsedTime = useState<Duration>(Duration.zero);

elapsedTimeは、ストップウォッチが記録した経過時間を保持するためのuseStateです。初期値はDuration.zero(0秒)です。

useEffect(() {
  Timer.periodic(Duration(seconds: 1), (Timer t) {
    if (timer.value?.isRunning ?? false) {
      elapsedTime.value = elapsedTime.value + Duration(seconds: 1);
    }
  });
  return null;
}, []);

useEffectを使用して、コンポーネントのマウント時に1秒ごとに実行されるタイマーを設定しています。このタイマーは、Stopwatchが動作している場合(timer.value?.isRunningtrue)、elapsedTimeの値を1秒ずつ増加させます。このフックはコンポーネントがマウントされたときにのみ実行されるので、配列の依存関係は空です。

ElevatedButton(
  onPressed: () {
    if (timer.value == null) {
      timer.value = Stopwatch()..start();
    } else {
      timer.value?.start();
    }
  },
  child: Text("開始"),
),

開始ボタンのonPressedコールバックです。もしストップウォッチがまだ開始されていない場合(timer.valuenull)、新しいStopwatchインスタンスを作成し、それを開始します。既に存在するStopwatchがある場合は、それを再開します。

ElevatedButton(
  onPressed: () {
    timer.value?.stop();
  },
  child: Text("一時停止"),
),

一時停止ボタンのonPressedコールバックです。ここで、ストップウォッチのstopメソッドを呼び出しています。これにより、ストップウォッチは一時停止されます。

ElevatedButton(
  onPressed: () {
    timer.value?.stop();
    elapsedTime.value = Duration.zero;
    timer.value = null;
  },
  child: Text("完了"),
),

完了ボタンのonPressedコールバックです。ここでは、まずストップウォッチを停止し、次にelapsedTimeを0にリセットし、最後にストップウォッチインスタンス自体をnullにリセットしています。これにより、完全に初期の状態に戻ります。

最後に

以上が、flutter_hooksを使用して、ストップウォッチの基本的な機能を実装したソースコードと解説でした。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?