Flutter如何监听应用事件:前后台切换、横竖屏切换、键盘显隐等

实现

在Flutter中可以通过WidgetsBindingaddObserver函数来监听应用事件,如下:

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,获取更多干货!

猜你喜欢

转载自blog.csdn.net/chzphoenix/article/details/126525435