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

Posted BennuCTech

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,获取更多干货!

以上是关于Flutter如何监听应用事件:前后台切换横竖屏切换键盘显隐等的主要内容,如果未能解决你的问题,请参考以下文章

面试题:Activity横竖屏切换时的生命周期如何变化

Android技术分享| 开源Demo any自习室布局架构

Android技术分享| 开源Demo any自习室布局架构

Flutter 监听 Stateless Widget 上的生命周期事件?

移动设备横竖屏监听事件

Flutter实战之Flutter应用生命周期 AppLifecycleState浅析