Created
July 6, 2023 05:33
-
-
Save amerblackbird/60d727132ba67a0ab989ca5e8eebffec to your computer and use it in GitHub Desktop.
RouteObserverWithCancelableOperation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'package:flutter/material.dart'; | |
import 'package:async/async.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>(); | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), | |
useMaterial3: true, | |
), | |
home: const HomePage(), | |
navigatorObservers: [routeObserver], | |
); | |
} | |
} | |
class HomePage extends StatefulWidget { | |
const HomePage({Key? key}) : super(key: key); | |
@override | |
State<HomePage> createState() => _HomePageState(); | |
} | |
class _HomePageState extends State<HomePage> with RouteAware { | |
/// An asynchronous operation that can be cancelled. | |
/// | |
/// Executes [_handleSomething] | |
CancelableOperation? _connectOperation; | |
/// Called when the current route has been pushed, from [RouteAware]. | |
@override | |
void didPush() { | |
debugPrint('HomePage: Called didPush'); | |
super.didPush(); | |
} | |
/// Called when the current route has been popped off, from [RouteAware]. | |
@override | |
void didPop() { | |
debugPrint('HomePage: Called didPop'); | |
super.didPop(); | |
} | |
/// Called when the top route has been popped off, and the current route, from [RouteAware]. | |
/// shows up. | |
/// | |
/// You can check stats of [_connectOperation] when user navigates back to this screen. | |
@override | |
void didPopNext() { | |
debugPrint("Ops status : ${_connectOperation?.isCanceled}"); | |
debugPrint("Ops status : ${_connectOperation?.isCompleted}"); | |
super.didPopNext(); | |
} | |
/// Called when a new route has been pushed, and the current route is no | |
/// longer visible. | |
/// | |
/// Cancel [_connectOperation] when user navigates to [SecondPage]. | |
@override | |
void didPushNext() { | |
if (_connectOperation != null && !_connectOperation!.isCompleted) { | |
_connectOperation?.cancel(); // Cancel operation. | |
} | |
debugPrint('HomePage: Called didPushNext'); | |
super.didPushNext(); | |
} | |
/// Run you tasks. | |
/// | |
/// Uses [Future.delayed] to delay the execution. | |
/// You can use [Timer] or [Timer.periodic]. | |
Future<dynamic> _handleSomething() async { | |
await Future.delayed(const Duration(minutes: 1)); | |
debugPrint('Running your work after 15 seconds ....'); | |
} | |
@override | |
void initState() { | |
super.initState(); | |
_connectOperation = CancelableOperation.fromFuture(_handleSomething()); | |
} | |
@override | |
void didChangeDependencies() { | |
super.didChangeDependencies(); | |
routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute); | |
} | |
@override | |
void dispose() { | |
routeObserver.unsubscribe(this); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
backgroundColor: Colors.cyan, | |
automaticallyImplyLeading: false, | |
title: const Text('Flutter RouteAware Demo'), | |
), | |
body: Center( | |
child: Padding( | |
padding: const EdgeInsets.all(16.0), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
children: [ | |
SizedBox( | |
height: MediaQuery.of(context).size.height * 0.25, | |
), | |
ElevatedButton( | |
style: ElevatedButton.styleFrom( | |
textStyle: const TextStyle(fontSize: 20), | |
minimumSize: const Size.fromHeight(40), | |
), | |
onPressed: () => Navigator.of(context).push( | |
MaterialPageRoute( | |
builder: (context) => const SecondPage(), | |
), | |
), | |
child: const Text( | |
"Home Page", | |
)), | |
], | |
), | |
), | |
), | |
); | |
} | |
} | |
class SecondPage extends StatefulWidget { | |
const SecondPage({Key? key}) : super(key: key); | |
@override | |
State<SecondPage> createState() => _SecondPageState(); | |
} | |
class _SecondPageState extends State<SecondPage> { | |
@override | |
void initState() { | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
backgroundColor: Colors.cyan, | |
title: const Text('Second Page'), | |
), | |
body: const Center( | |
child: Text( | |
"Flutter Dev's", | |
style: TextStyle(fontSize: 35.0), | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment