Skip to content

Instantly share code, notes, and snippets.

@davidhicks980
Last active December 31, 2022 11:34
Show Gist options
  • Save davidhicks980/57e57e674293dd72bca1340e9e8ebac6 to your computer and use it in GitHub Desktop.
Save davidhicks980/57e57e674293dd72bca1340e9e8ebac6 to your computer and use it in GitHub Desktop.
Flutter: Listen to page transition status
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const PageTransitionDemo());
}
/// Demonstrates how to show a widget after a page is finished transitioning
class PageTransitionDemo extends StatelessWidget {
const PageTransitionDemo({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
initialRoute: "/",
routes: {
"/": (context) => const Origin(),
},
);
}
}
/// Sample Origin page -- does not contain any relevant logic
class Origin extends StatelessWidget {
const Origin({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Origin"),
),
body: Center(
child: TextButton(
onPressed: () {
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 5000),
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return CupertinoPageTransition(
primaryRouteAnimation: animation,
secondaryRouteAnimation: secondaryAnimation,
linearTransition: false,
child: const Destination(),
);
},
),
);
},
child: const Text("Go to destination"),
),
),
);
}
}
class Destination extends StatefulWidget {
const Destination({super.key});
@override
State<Destination> createState() => _DestinationState();
}
class _DestinationState extends State<Destination> {
bool isWidgetVisible = false;
Animation<double>? get transitionIn => ModalRoute.of(context)?.animation;
@override
void initState() {
super.initState();
/// Add post frame callback so that we can access BuildContext
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
///Listen for page animation status changes
transitionIn?.addStatusListener(_handleCompletedPageTransition);
});
}
/// Unsubscribes animation status listener and toggles isWidgetVisible
/// once our forward animation completes
void _handleCompletedPageTransition(AnimationStatus status) {
if (status == AnimationStatus.completed) {
transitionIn?.removeStatusListener(_handleCompletedPageTransition);
setState(() {
isWidgetVisible = true;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Destination"),
backgroundColor: Colors.black,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (isWidgetVisible)
const Center(
child: Text(
'Animation completed',
style: TextStyle(fontSize: 32),
),
)
else
AnimatedBuilder(
animation: transitionIn!,
builder: ((context, child) {
return Column(
children: [
CircularProgressIndicator(
value: transitionIn!.value,
color: Color.lerp(
Colors.blue,
Colors.green,
transitionIn!.value,
),
),
const SizedBox(height: 20),
Text(
"Transition Progress ${transitionIn!.value.toStringAsPrecision(3)}",
style: const TextStyle(fontSize: 20),
),
],
);
}),
),
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment