实现
在Flutter中可以通过WidgetsBinding
的addObserver
函数来监听应用事件,如下:
WidgetsBinding.instance.addObserver(observer);
//WidgetsBinding.instance.removeObserver(observer);
这里的observer就是WidgetsBindingObserver对象,WidgetsBindingObserver是一个接口,需要我们继承实现它。下面看看它有哪些事件
WidgetsBindingObserver
WidgetsBindingObserver源码如下:
/// Interface for classes that register with the Widgets layer binding.
///
/// When used as a mixin, provides no-op method implementations.
///
/// See [WidgetsBinding.addObserver] and [WidgetsBinding.removeObserver].
///
/// This class can be extended directly, to get default behaviors for all of the
/// handlers, or can used with the `implements` keyword, in which case all the
/// handlers must be implemented (and the analyzer will list those that have
/// been omitted).
///
/// {@tool snippet}
///
/// This [StatefulWidget] implements the parts of the [State] and
/// [WidgetsBindingObserver] protocols necessary to react to application
/// lifecycle messages. See [didChangeAppLifecycleState].
///
/// ```dart
/// class AppLifecycleReactor extends StatefulWidget {
/// const AppLifecycleReactor({ Key? key }) : super(key: key);
///
/// @override
/// _AppLifecycleReactorState createState() => _AppLifecycleReactorState();
/// }
///
/// class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver {
/// @override
/// void initState() {
/// super.initState();
/// WidgetsBinding.instance!.addObserver(this);
/// }
///
/// @override
/// void dispose() {
/// WidgetsBinding.instance!.removeObserver(this);
/// super.dispose();
/// }
///
/// late AppLifecycleState _notification;
///
/// @override
/// void didChangeAppLifecycleState(AppLifecycleState state) {
/// setState(() { _notification = state; });
/// }
///
/// @override
/// Widget build(BuildContext context) {
/// return Text('Last notification: $_notification');
/// }
/// }
/// ```
/// {@end-tool}
///
/// To respond to other notifications, replace the [didChangeAppLifecycleState]
/// method above with other methods from this class.
abstract class WidgetsBindingObserver {
/// Called when the system tells the app to pop the current route.
/// For example, on Android, this is called when the user presses
/// the back button.
///
/// Observers are notified in registration order until one returns
/// true. If none return true, the application quits.
///
/// Observers are expected to return true if they were able to
/// handle the notification, for example by closing an active dialog
/// box, and false otherwise. The [WidgetsApp] widget uses this
/// mechanism to notify the [Navigator] widget that it should pop
/// its current route if possible.
///
/// This method exposes the `popRoute` notification from
/// [SystemChannels.navigation].
Future<bool> didPopRoute() => Future<bool>.value(false);
/// Called when the host tells the application to push a new route onto the
/// navigator.
///
/// Observers are expected to return true if they were able to
/// handle the notification. Observers are notified in registration
/// order until one returns true.
///
/// This method exposes the `pushRoute` notification from
/// [SystemChannels.navigation].
Future<bool> didPushRoute(String route) => Future<bool>.value(false);
/// Called when the host tells the application to push a new
/// [RouteInformation] and a restoration state onto the router.
///
/// Observers are expected to return true if they were able to
/// handle the notification. Observers are notified in registration
/// order until one returns true.
///
/// This method exposes the `pushRouteInformation` notification from
/// [SystemChannels.navigation].
///
/// The default implementation is to call the [didPushRoute] directly with the
/// [RouteInformation.location].
Future<bool> didPushRouteInformation(RouteInformation routeInformation) {
return didPushRoute(routeInformation.location!);
}
/// Called when the application's dimensions change. For example,
/// when a phone is rotated.
///
/// This method exposes notifications from
/// [dart:ui.PlatformDispatcher.onMetricsChanged].
///
/// {@tool snippet}
///
/// This [StatefulWidget] implements the parts of the [State] and
/// [WidgetsBindingObserver] protocols necessary to react when the device is
/// rotated (or otherwise changes dimensions).
///
/// ```dart
/// class MetricsReactor extends StatefulWidget {
/// const MetricsReactor({ Key? key }) : super(key: key);
///
/// @override
/// _MetricsReactorState createState() => _MetricsReactorState();
/// }
///
/// class _MetricsReactorState extends State<MetricsReactor> with WidgetsBindingObserver {
/// late Size _lastSize;
///
/// @override
/// void initState() {
/// super.initState();
/// _lastSize = WidgetsBinding.instance!.window.physicalSize;
/// WidgetsBinding.instance!.addObserver(this);
/// }
///
/// @override
/// void dispose() {
/// WidgetsBinding.instance!.removeObserver(this);
/// super.dispose();
/// }
///
/// @override
/// void didChangeMetrics() {
/// setState(() { _lastSize = WidgetsBinding.instance!.window.physicalSize; });
/// }
///
/// @override
/// Widget build(BuildContext context) {
/// return Text('Current size: $_lastSize');
/// }
/// }
/// ```
/// {@end-tool}
///
/// In general, this is unnecessary as the layout system takes care of
/// automatically recomputing the application geometry when the application
/// size changes.
///
/// See also:
///
/// * [MediaQuery.of], which provides a similar service with less
/// boilerplate.
void didChangeMetrics() {
}
/// Called when the platform's text scale factor changes.
///
/// This typically happens as the result of the user changing system
/// preferences, and it should affect all of the text sizes in the
/// application.
///
/// This method exposes notifications from
/// [dart:ui.PlatformDispatcher.onTextScaleFactorChanged].
///
/// {@tool snippet}
///
/// ```dart
/// class TextScaleFactorReactor extends StatefulWidget {
/// const TextScaleFactorReactor({ Key? key }) : super(key: key);
///
/// @override
/// _TextScaleFactorReactorState createState() => _TextScaleFactorReactorState();
/// }
///
/// class _TextScaleFactorReactorState extends State<TextScaleFactorReactor> with WidgetsBindingObserver {
/// @override
/// void initState() {
/// super.initState();
/// WidgetsBinding.instance!.addObserver(this);
/// }
///
/// @override
/// void dispose() {
/// WidgetsBinding.instance!.removeObserver(this);
/// super.dispose();
/// }
///
/// late double _lastTextScaleFactor;
///
/// @override
/// void didChangeTextScaleFactor() {
/// setState(() { _lastTextScaleFactor = WidgetsBinding.instance!.window.textScaleFactor; });
/// }
///
/// @override
/// Widget build(BuildContext context) {
/// return Text('Current scale factor: $_lastTextScaleFactor');
/// }
/// }
/// ```
/// {@end-tool}
///
/// See also:
///
/// * [MediaQuery.of], which provides a similar service with less
/// boilerplate.
void didChangeTextScaleFactor() {
}
/// Called when the platform brightness changes.
///
/// This method exposes notifications from
/// [dart:ui.PlatformDispatcher.onPlatformBrightnessChanged].
void didChangePlatformBrightness() {
}
/// Called when the system tells the app that the user's locale has
/// changed. For example, if the user changes the system language
/// settings.
///
/// This method exposes notifications from
/// [dart:ui.PlatformDispatcher.onLocaleChanged].
void didChangeLocales(List<Locale>? locales) {
}
/// Called when the system puts the app in the background or returns
/// the app to the foreground.
///
/// An example of implementing this method is provided in the class-level
/// documentation for the [WidgetsBindingObserver] class.
///
/// This method exposes notifications from [SystemChannels.lifecycle].
void didChangeAppLifecycleState(AppLifecycleState state) {
}
/// Called when the system is running low on memory.
///
/// This method exposes the `memoryPressure` notification from
/// [SystemChannels.system].
void didHaveMemoryPressure() {
}
/// Called when the system changes the set of currently active accessibility
/// features.
///
/// This method exposes notifications from
/// [dart:ui.PlatformDispatcher.onAccessibilityFeaturesChanged].
void didChangeAccessibilityFeatures() {
}
}
可以看到它包含如下事件:
- didPopRoute:当退出页面的时候触发
- didPushRoute:当打开页面的时候触发
- didPushRouteInformation:同上
- didChangeMetrics:当应用尺寸宽高的时候执行。比如横竖屏切换,键盘显隐等
- didChangeTextScaleFactor:当系统字体大小改变的触发。比如在系统设置中修改为超大字体
- didChangePlatformBrightness:当屏幕亮度改变时触发
- didChangeLocales:当locale改变时触发,比如改变系统语言
- didChangeAppLifecycleState:前后台切换时触发
- didHaveMemoryPressure:当处于low memory时触发
- didChangeAccessibilityFeatures:当系统无障碍设置改变时触发
我们通过这些函数就可以处理如前后台切换、横竖屏切换、键盘显隐等事件。
关注公众号:BennuCTech,获取更多干货!