Flutter学习记录——14.生命周期

r囧r小猫 2023-06-19 05:29 83阅读 0赞

文章目录

  • 1.Flutter生命周期
  • 2.Flutter按键监听
  • 3.总结

1.Flutter生命周期

我们先了解下生命周期的概念,也就是一个页面对象从创建到销毁的整个状态管理。我们看下 Flutter 的 State 生命周期的示意图:
生命周期

可以看到我们的一个页面在加载创建时需要执行:

构造函数 -> initState -> didChangeDependencies -> build 方法,然后才会渲染为一个页面。

当销毁关闭时:

deactivate -> dispose

内部的前后台页面状态变化主要有:

  1. enum AppLifecycleState {
  2. // 恢复可见
  3. resumed,
  4. // 不可见,后台运行,无法处理用户响应
  5. inactive,
  6. // 处在并不活动状态,无法处理用户响应。例如来电,画中画,弹框
  7. paused,
  8. // 应用被立刻暂停挂起,ios上不会回调这个状态
  9. suspending,
  10. }

当页面更新时会执行:

didUpdateWidget -> build

可能会调用多次。

那么接下来通过代码实例来了解 Flutter 的生命周期:

  1. import 'package:flutter/material.dart';
  2. class StateSamples extends StatefulWidget {
  3. @override
  4. State<StatefulWidget> createState() {
  5. return StateSamplesState();
  6. }
  7. }
  8. class StateSamplesState extends State<StateSamples>
  9. with WidgetsBindingObserver {
  10. //插入渲染树时调用,只调用一次
  11. @override
  12. void initState() {
  13. super.initState();
  14. WidgetsBinding.instance.addObserver(this);
  15. }
  16. //构建Widget时调用
  17. @override
  18. Widget build(BuildContext context) {
  19. return Scaffold(
  20. appBar: AppBar(
  21. title: Text('LifeCycleState'),
  22. ),
  23. body: Center(
  24. child: Column(
  25. children: <Widget>[],
  26. ),
  27. ),
  28. );
  29. }
  30. //state依赖的对象发生变化时调用
  31. @override
  32. void didChangeDependencies() {
  33. super.didChangeDependencies();
  34. }
  35. //组件状态改变时候调用,可能会调用多次
  36. @override
  37. void didUpdateWidget(StateSamples oldWidget) {
  38. super.didUpdateWidget(oldWidget);
  39. }
  40. //当移除渲染树的时候调用
  41. @override
  42. void deactivate() {
  43. super.deactivate();
  44. }
  45. //组件即将销毁时调用
  46. @override
  47. void dispose() {
  48. super.dispose();
  49. WidgetsBinding.instance.removeObserver(this);
  50. }
  51. //APP生命周期监听
  52. @override
  53. void didChangeAppLifecycleState(AppLifecycleState state) {
  54. if (state == AppLifecycleState.resumed) {
  55. //恢复可见
  56. } else if (state == AppLifecycleState.paused) {
  57. //处在并不活动状态,无法处理用户响应
  58. //例如来电,画中画,弹框
  59. } else if (state == AppLifecycleState.inactive) {
  60. //不可见,后台运行,无法处理用户响应
  61. } else if (state == AppLifecycleState.suspending) {
  62. //应用被立刻暂停挂起,ios上不会回调
  63. }
  64. super.didChangeAppLifecycleState(state);
  65. }
  66. //其他方法
  67. //热重载时调用
  68. @override
  69. void reassemble() {
  70. super.reassemble();
  71. }
  72. //路由弹出
  73. @override
  74. Future<bool> didPopRoute() {
  75. return super.didPopRoute();
  76. }
  77. //新的路由
  78. @override
  79. Future<bool> didPushRoute(String route) {
  80. return super.didPushRoute(route);
  81. }
  82. //系统窗口相关改变回调,例如旋转
  83. @override
  84. void didChangeMetrics() {
  85. super.didChangeMetrics();
  86. }
  87. //文字缩放大小变化
  88. @override
  89. void didChangeTextScaleFactor() {
  90. super.didChangeTextScaleFactor();
  91. }
  92. //本地化语言变化
  93. @override
  94. void didChangeLocales(List<Locale> locale) {
  95. super.didChangeLocales(locale);
  96. }
  97. //低内存回调
  98. @override
  99. void didHaveMemoryPressure() {
  100. super.didHaveMemoryPressure();
  101. }
  102. //当前系统改变了一些访问性活动的回调
  103. @override
  104. void didChangeAccessibilityFeatures() {
  105. super.didChangeAccessibilityFeatures();
  106. }
  107. //平台色调主题变化时
  108. @override
  109. void didChangePlatformBrightness() {
  110. super.didChangePlatformBrightness();
  111. }
  112. }

2.Flutter按键监听

我们知道在 Android 或 iOS 平台上,手机上或遥控器上的一些实体按键是可以被监听到的,可以执行相关操作,当然 Flutter 上也可以进行按键监听。

首先看下返回键的监听,返回键监听拦截在 Flutter 中比较不一样。是单独使用一个组件:WillPopScope。

然后通过一个实例来看下 Flutter 中实现连按两次返回键退出的效果:

  1. class KeyListenerState extends State<KeyListenerSamples> {
  2. int last = 0;
  3. int index = 0;
  4. @override
  5. void initState() {
  6. super.initState();
  7. }
  8. @override
  9. Widget build(BuildContext context) {
  10. // 要用WillPopScope包裹
  11. return WillPopScope(
  12. // 编写onWillPop逻辑
  13. onWillPop: _onWillPop,
  14. child: Scaffold(
  15. appBar: AppBar(
  16. title: Text('KeyListener Demo'),
  17. ),
  18. body: Center(
  19. child: Text("按键监听"),
  20. )),
  21. );
  22. }
  23. // 返回键拦截执行方法
  24. Future<bool> _onWillPop() {
  25. int now = DateTime.now().millisecondsSinceEpoch;
  26. print(now - last);
  27. if (now - last > 1000) {
  28. last = now;
  29. // showToast("再按一次返回键退出");
  30. return Future.value(false); //不退出
  31. } else {
  32. return Future.value(true); //退出
  33. }
  34. }
  35. }

那么其他按键的监听使用的是 RawKeyboardListener。

RawKeyboardListener 继承自 StatefulWidget。

  1. const RawKeyboardListener({
  2. Key key,
  3. // 焦点节点
  4. @required this.focusNode,
  5. // RawKeyEvent,按键事件
  6. @required this.onKey,
  7. // 子控件
  8. @required this.child,
  9. })

我们再看下 RawKeyEvent 的构造方法:

  1. const RawKeyEvent({
  2. // RawKeyEventData
  3. @required this.data,
  4. this.character,
  5. })

监听 Android 平台使用 RawKeyEventDataAndroid,监听 Fuchsia 平台使用RawKeyEventDataFuchsia,iOS 平台暂时还没有发布。

RawKeyboardListener 用法:

  1. class KeyListenerState extends State<KeyListenerSamples> {
  2. FocusNode focusNode = FocusNode();
  3. @override
  4. void initState() {
  5. super.initState();
  6. FocusScope.of(context).requestFocus(focusNode);
  7. }
  8. @override
  9. Widget build(BuildContext context) {
  10. return Scaffold(
  11. appBar: AppBar(
  12. title: Text('RawKeyboardListener Demo'),
  13. ),
  14. // RawKeyboardListener包裹
  15. body: RawKeyboardListener(
  16. // 可以监听到的前提是有焦点,我们可以让组件先获取焦点
  17. focusNode: focusNode,
  18. onKey: (RawKeyEvent event) {
  19. // 这里是监听Android平台按键,并且是KeyDown事件
  20. if (event is RawKeyDownEvent &&
  21. event.data is RawKeyEventDataAndroid) {
  22. RawKeyDownEvent rawKeyDownEvent = event;
  23. RawKeyEventDataAndroid rawKeyEventDataAndroid =
  24. rawKeyDownEvent.data;
  25. print("keyCode: ${ rawKeyEventDataAndroid.keyCode}");
  26. switch (rawKeyEventDataAndroid.keyCode) {
  27. // 这里面的KeyCode值和Android平台的一致
  28. case 19: //KEY_UP
  29. break;
  30. case 20: //KEY_DOWN
  31. break;
  32. case 21: //KEY_LEFT
  33. break;
  34. case 22: //KEY_RIGHT
  35. break;
  36. case 23: //KEY_CENTER
  37. break;
  38. default:
  39. break;
  40. }
  41. }
  42. },
  43. child: Center(
  44. child: Text("按键监听"),
  45. )),
  46. );
  47. }
  48. }

当然我们也可以把 RawKeyboardListener 应用在输入框的焦点获取和监听上。

3.总结

本节课主要是给大家讲解了 Flutter 的生命周期和按键监听的用法和特点。主要注意点和建议如下:

  • 重点掌握 Flutter 生命周期的几个状态和返回键的拦截处理的用法。
  • 尝试编写监听输入框的按键事件和焦点事件。

发表评论

表情:
评论列表 (有 0 条评论,83人围观)

还没有评论,来说两句吧...

相关阅读