It's probably not the simplest and definitely not perfect, but a while back I implemented events like those with routes. Basically, EventRoute<T>
is a drop-in replacement for MaterialPageRoute<T>
that provides optional callbacks for when the Widget is created, pushed to the foreground, pushed to the background and when it gets popped off.
event_route.dart:
import 'package:flutter/material.dart';
enum RouteState {
none,
created,
foreground,
background,
destroyed
}
class EventRoute<T> extends MaterialPageRoute<T> {
BuildContext _context;
RouteState _state;
Function(BuildContext) _onCreateCallback;
Function(BuildContext) _onForegroundCallback;
Function(BuildContext) _onBackgroundCallback;
Function(BuildContext) _onDestroyCallback;
EventRoute(BuildContext context, {
builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,
Function(BuildContext) onCreate,
Function(BuildContext) onForeground,
Function(BuildContext) onBackground,
Function(BuildContext) onDestroy
}):
_context = context,
_onCreateCallback = onCreate,
_onForegroundCallback = onForeground,
_onBackgroundCallback = onBackground,
_onDestroyCallback = onDestroy,
_state = RouteState.none,
super(builder: builder, settings: settings, maintainState: maintainState, fullscreenDialog: fullscreenDialog);
void get state => _state;
@override
void didChangeNext(Route nextRoute) {
if (nextRoute == null) {
_onForeground();
} else {
_onBackground();
}
super.didChangeNext(nextRoute);
}
@override
bool didPop(T result) {
_onDestroy();
return super.didPop(result);
}
@override
void didPopNext(Route nextRoute) {
_onForeground();
super.didPopNext(nextRoute);
}
@override
TickerFuture didPush() {
_onCreate();
return super.didPush();
}
@override
void didReplace(Route oldRoute) {
_onForeground();
super.didReplace(oldRoute);
}
void _onCreate() {
if (_state != RouteState.none || _onCreateCallback == null) {
return;
}
_onCreateCallback(_context);
}
void _onForeground() {
if (_state == RouteState.foreground) {
return;
}
_state = RouteState.foreground;
if (_onForegroundCallback != null) {
_onForegroundCallback(_context);
}
}
void _onBackground() {
if (_state == RouteState.background) {
return;
}
_state = RouteState.background;
if (_onBackgroundCallback != null) {
_onBackgroundCallback(_context);
}
}
void _onDestroy() {
if (_state == RouteState.destroyed || _onDestroyCallback == null) {
return;
}
_onDestroyCallback(_context);
}
}
And then to push your route you do:
Navigator.push(context, EventRoute(context, builder: (context) => YourWidget(context),
onCreate: (context) => print('create'),
onForeground: (context) => print('foreground'),
onBackground: (context) => print('background'),
onDestroy: (context) => print('destroy')
));
The context is a little icky though...
didChangeAppLifecycleState
. My use case is different @Tokenyet – FibroidNavigator.pop(context, parameter)
, so in the video screen you will get the parameter and do something accordingly. See this post https://mcmap.net/q/161707/-passing-data-between-screens-in-flutter – TransitiveonResume
. It's more about PageTransition, and look like you have the workaround. For not talking too much code, I prefer to stop beforeNavigator.push
andawait Navigator.pop
to resume video. If you are not usingNavigator
, you might need to provide more code to show us :P – Surinam