【Flutter】特定の画面で表示時間をStopwatchで計測したい。
はじめに
はじめまして。たけです。
初稿です。よろしくお願いします🌱
今回は、Flutterプロジェクトで特定の画面の表示時間を計測する機能についてまとめました。
この機能は、ユーザーがどれくらいその画面を見ていたかを把握する際に便利です。
アプリの使いやすさの改善や、特定のコンテンツへの関心度を測るためのデータとして利用します。
実装方法
-
riverpod
,state_notifier
,freezed
を使用して、この機能を実装する方法を説明します。 - 経過時間を測るには、
Stopwatch
クラスを使います。 - アプリのライフサイクルを管理し、特定の画面が表示されている時間をストップウォッチで計測します。
考慮する点
- アプリのライフサイクルを適切に管理し、バックグラウンドとフォアグラウンドの状態を識別できるようにする。
-
Freezed
パッケージを利用して状態を管理し、コードの保守性と安全性を確保する。 -
Riverpod
,StateNotifier
を利用して状態管理を行うことで、状態の流れを明確にし、テストやデバッグを容易にする。
では、実装手順を見ていきましょう。
ステップ1: 依存関係の追加
プロジェクトのpubspec.yaml
に以下の依存関係を追加します。バージョンはそれぞれの最新を指定してください。
dependencies:
flutter:
sdk: flutter
hooks_riverpod: ^最新のバージョン
freezed_annotation: ^最新のバージョン
state_notifier: ^最新のバージョン
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^最新のバージョン
freezed: ^最新のバージョン
ステップ2: Freezedクラスの作成
sample_state.dart
に、以下のコードを追加してSampleScreenState
を定義します。
import 'package:freezed_annotation/freezed_annotation.dart';
part 'sample_state.freezed.dart';
class SampleScreenState with _$SampleScreenState {
const SampleScreenState._();
const factory SampleScreenState({
(Duration.zero) Duration totalDuration,
}) = _SampleScreenState;
}
ステップ3: StateNotifierの作成
sample_screen_controller.dart
に、以下のコードを追加してSampleScreenController
を定義します。
didChangeAppLifecycleState
では、アプリのライフサイクルを適切に管理し、バックグラウンドとフォアグラウンドの状態を識別できるようにしています。
import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
import 'sample_state.dart';
class SampleScreenController extends StateNotifier<SampleScreenState>
with WidgetsBindingObserver {
SampleScreenController() : super(const SampleScreenState()) {
WidgetsBinding.instance.addObserver(this); // アプリのライフサイクルを監視
_stopwatch.start(); // ストップウォッチを開始
}
final Stopwatch _stopwatch = Stopwatch(); // ストップウォッチのインスタンスを作成
void dispose() {
WidgetsBinding.instance?.removeObserver(this); // アプリのライフサイクルの監視を停止
_stopwatch.stop(); // ストップウォッチを停止
state = state.copyWith(totalDuration: _stopwatch.elapsed); // 総経過時間を更新
super.dispose();
}
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// アプリが前面に戻ったときにタイマーを再開
_stopwatch.start();
} else if (state == AppLifecycleState.paused) {
// アプリが背景に移動したときにタイマーを停止
_stopwatch.stop();
}
}
}
ステップ4: プロバイダの作成
次に、プロバイダを作成します。sample_provider.dart
にプロバイダを定義します。
import 'package:riverpod/riverpod.dart';
import 'sample_screen_controller.dart';
import 'sample_state.dart';
final sampleScreenProvider = StateNotifierProvider<SampleScreenController, SampleScreenState>(
(ref) => SampleScreenController(),
);
ステップ5: Widgetの作成
sample_screen.dart
に、SampleScreen
を定義します。
このステップでは、アプリの特定の画面の表示時間を計測し、その時間を画面に表示する仕組みを作成します。
import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
import 'sample_provider.dart';
class SampleScreen extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final state = ref.watch(sampleScreenProvider); // 状態を監視
return Scaffold(
appBar: AppBar(
title: Text('Sample Screen'),
),
body: Center(
child: Text('Total Duration: ${state.totalDuration.inSeconds} seconds'), // 総経過時間を表示
),
);
}
}
ステップ6: UIの更新
SampleScreen
でElevatedButton
を使用して表示した時間を表示するupdateDuration
メソッドと時間をリセットするresetDuration
メソッドを呼び出し、計測した経過時間をStringとして表示できるようにします。
まず、SampleScreenController
でupdateDuration
メソッドを作成し、以下のように実装します。
void updateDuration() {
state = state.copyWith(totalDuration: _stopwatch.elapsed); // 総経過時間を更新
}
void resetDuration() {
_stopwatch.reset();
state = state.copyWith(totalDuration: _stopwatch.elapsed);
_stopwatch.start();
}
次に、SampleScreen
でupdateDuration
メソッドとresetDuration
メソッドを呼び出すとともに、経過時間をStringで表示できるようにします。
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Total Duration: ${state.totalDuration.inSeconds} seconds',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const Gap(30),
//時間計測出力ボタン
ElevatedButton(
onPressed: () {
ref
.read(sampleScreenProvider.notifier)
.updateDuration(); // updateDurationメソッドを呼び出し
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Total Duration: ${ref.watch(sampleScreenProvider).totalDuration}'), // 総経過時間をStringで表示
),
);
},
child: Text(
' Stop',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
//時間計測リセットボタン
ElevatedButton(
onPressed: () {
ref
.read(sampleScreenProvider.notifier)
.resetDuration(); // updateDurationメソッドを呼び出し
},
child: Text(
' Reset',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
],
), // 総経過時間を表示
),
操作確認動画
まとめ
最後まで読んでくださりありがとうございます。
今回はFlutterで特定の画面を表示している時間を計測Stopwatchクラスを活用する方法を紹介してみました!
気になる点がありましたらお声がけください!
よろしければ、ハート・フォロー・シェアをいただけますと喜びます :)
Discussion