Skip to content

Instantly share code, notes, and snippets.

@ueman
Created February 2, 2024 15:51
Show Gist options
  • Save ueman/1e31444d845a1c763bcd1505a4545e33 to your computer and use it in GitHub Desktop.
Save ueman/1e31444d845a1c763bcd1505a4545e33 to your computer and use it in GitHub Desktop.
hacky virtual navigation
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void navigate(BuildContext context) {
Navigator.push<void>(
context,
NativePageRoute(
onPush: () => openAppSetttings(),
onResume: () => Future.value(),
),
);
}
class NativePageRoute<T> extends PageRoute<T> {
/// Creates a route that delegates to builder callbacks.
NativePageRoute({
required this.onPush,
required this.onResume,
super.settings,
this.maintainState = true,
super.fullscreenDialog,
super.allowSnapshotting = true,
});
final VoidCallback onPush;
final Future<T> Function() onResume;
@override
final Duration transitionDuration = Duration.zero;
@override
final Duration reverseTransitionDuration = Duration.zero;
@override
final bool opaque = false;
@override
final bool barrierDismissible = false;
@override
final Color? barrierColor = null;
@override
final String? barrierLabel = null;
@override
final bool maintainState;
@override
Widget buildPage(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return NativePage(
onPush: onPush,
onResume: onResume,
);
}
@override
Widget buildTransitions(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return child;
}
}
class NativePage<T> extends StatefulWidget {
const NativePage({super.key, required this.onPush, required this.onResume});
final VoidCallback onPush;
final Future<T> Function() onResume;
@override
State<NativePage> createState() => _NativePageState();
}
class _NativePageState extends State<NativePage> {
late final AppLifecycleListener _listener;
@override
void initState() {
super.initState();
_listener = AppLifecycleListener(onResume: _onResume);
widget.onPush();
}
@override
void dispose() {
_listener.dispose();
super.dispose();
}
void _onResume() async {
final t = await widget.onResume();
if (context.mounted) {
Navigator.pop(context, t);
}
}
@override
Widget build(BuildContext context) {
return const SizedBox.shrink();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment