2026.04.26 dart  
 2026.04.26 dart  
 2026.04.25 dart  
 2026.04.19 dart  
 2026.04.19 dart  
 2026.04.19 dart  
 2026.04.15 未分類  

riverpodtimer


main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'dart:async'; // Timerに必要
import 'package:intl/intl.dart'; // 日付フォーマットに必要
// 1. 1秒ごとに現在時刻をStreamで流すProvider
final dateTimeStreamProvider = StreamProvider((ref) {
// periodicは指定したDurationごとに処理を実行する
return Stream.periodic(const Duration(seconds: 1), (_) => DateTime.now())
 .startWith(DateTime.now()); // 最初の一回は即座に時間を表示
});

void main() {
runApp(
 // Riverpodを利用するためにProviderScopeで囲む
const ProviderScope(child: MyApp()),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
 Widget build(BuildContext context) {
 return MaterialApp(
 home: ClockScreen(),
 );
}
}

class ClockScreen extends ConsumerWidget {
 const ClockScreen({super.key});

 @override
 Widget build(BuildContext context, WidgetRef ref) {
  // 2. ProviderをWatchする
 final asyncDateTime = ref.watch(dateTimeStreamProvider);
 return Scaffold(
 appBar: AppBar(title: const Text('Riverpod 現在時刻')),
 body: Center(
  child: asyncDateTime.when(
  data: (dateTime) {
// 3. 日付と時刻のフォーマット
 final dateStr = DateFormat('yyyy年MM月dd日 (E)').format(dateTime);
 final timeStr = DateFormat('HH:mm:ss').format(dateTime);
 return Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
  Text(dateStr, style: const TextStyle(fontSize: 24)),
  const SizedBox(height: 10),
  Text(timeStr, style: const TextStyle(fontSize: 48, fontWeight: FontWeight.bold)),
 ],
);
},
 loading: () => const CircularProgressIndicator(),
  error: (error, stack) => Text('Error: $error'),
 ),
 ),
 );
}
}
// Streamの最初の読み込みをスキップしないための拡張機能
extension StreamExtension on Stream {
 Stream startWith(T value) {
 return Stream.multi((controller) {
 controller.add(value);
 this.listen(controller.add);
  });
 }
}
カテゴリー: dart