I am implementing a timer in flutter .Here is the structure of the app.
Page A (Contains some lists where user clicks and takes it to timer Page). Page B formats ,runs t
Here is a minimal working solution. Key points:
TimerService
class that isolates the timer functionalityTimerService
implements ChangeNotifier
, which you can subscribe to to receive changes.InheritedWidget
is used to provide the service to all widgets of your app. This inherited widget wraps your app widget.AnimatedBuilder
is used to receive changes from the ChangeNotifier
. Subscriptions are handles automatically (no manual addListener
/removeListener
).import 'dart:async';
import 'package:flutter/material.dart';
void main() {
final timerService = TimerService();
runApp(
TimerServiceProvider( // provide timer service to all widgets of your app
service: timerService,
child: MyApp(),
),
);
}
class TimerService extends ChangeNotifier {
Stopwatch _watch;
Timer _timer;
Duration get currentDuration => _currentDuration;
Duration _currentDuration = Duration.zero;
bool get isRunning => _timer != null;
TimerService() {
_watch = Stopwatch();
}
void _onTick(Timer timer) {
_currentDuration = _watch.elapsed;
// notify all listening widgets
notifyListeners();
}
void start() {
if (_timer != null) return;
_timer = Timer.periodic(Duration(seconds: 1), _onTick);
_watch.start();
notifyListeners();
}
void stop() {
_timer?.cancel();
_timer = null;
_watch.stop();
_currentDuration = _watch.elapsed;
notifyListeners();
}
void reset() {
stop();
_watch.reset();
_currentDuration = Duration.zero;
notifyListeners();
}
static TimerService of(BuildContext context) {
var provider = context.inheritFromWidgetOfExactType(TimerServiceProvider) as TimerServiceProvider;
return provider.service;
}
}
class TimerServiceProvider extends InheritedWidget {
const TimerServiceProvider({Key key, this.service, Widget child}) : super(key: key, child: child);
final TimerService service;
@override
bool updateShouldNotify(TimerServiceProvider old) => service != old.service;
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Service Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
var timerService = TimerService.of(context);
return Scaffold(
appBar: AppBar(),
body: Center(
child: AnimatedBuilder(
animation: timerService, // listen to ChangeNotifier
builder: (context, child) {
// this part is rebuilt whenever notifyListeners() is called
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Elapsed: ${timerService.currentDuration}'),
RaisedButton(
onPressed: !timerService.isRunning ? timerService.start : timerService.stop,
child: Text(!timerService.isRunning ? 'Start' : 'Stop'),
),
RaisedButton(
onPressed: timerService.reset,
child: Text('Reset'),
)
],
);
},
),
),
);
}
}