dart Flutter上小部件的onResume()和onPause()

pxy2qtax  于 2023-09-28  发布在  Flutter
关注(0)|答案(7)|浏览(144)

现在,小部件只有initeState()和dispose(),initeState()在小部件第一次创建时被触发,dispose()在小部件被销毁时被触发。有没有一种方法可以检测小部件何时返回到前台?当一个小部件即将进入后台,因为另一个小部件刚刚被前景化?它相当于Android的onResume和onPause被触发,iOS的viewWillAppear和viewWillDisappear被触发

unhi4e5o

unhi4e5o1#

有一个抽象类调用者WidgetsBindingObserver
https://docs.flutter.io/flutter/widgets/WidgetsBindingObserver-class.html

  1. @override
  2. void didChangeAppLifecycleState(AppLifecycleState state) {
  3. setState(() {
  4. _notification = state;
  5. });
  6. }

存在“状态”,可以管理为

  1. switch(state) {
  2. case AppLifecycleState.resumed:
  3. // Handle this case
  4. break;
  5. case AppLifecycleState.inactive:
  6. // Handle this case
  7. break;
  8. case AppLifecycleState.paused:
  9. // Handle this case
  10. break;
  11. case AppLifecycleState.suspending:
  12. // Handle this case
  13. break;
  14. }
展开查看全部
pinkon5k

pinkon5k2#

这是一个完整的例子,演示了如何正确地处理事情,要测试这一点,按下主页按钮,并恢复应用程序,你会看到didChangeAppLifecycleState被调用。

  1. class HomePage extends StatefulWidget {
  2. @override
  3. _HomePageState createState() => _HomePageState();
  4. }
  5. class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
  6. @override
  7. void initState() {
  8. super.initState();
  9. // Add the observer.
  10. WidgetsBinding.instance!.addObserver(this);
  11. }
  12. @override
  13. void dispose() {
  14. // Remove the observer
  15. WidgetsBinding.instance!.removeObserver(this);
  16. super.dispose();
  17. }
  18. @override
  19. void didChangeAppLifecycleState(AppLifecycleState state) {
  20. super.didChangeAppLifecycleState(state);
  21. // These are the callbacks
  22. switch (state) {
  23. case AppLifecycleState.resumed:
  24. // widget is resumed
  25. break;
  26. case AppLifecycleState.inactive:
  27. // widget is inactive
  28. break;
  29. case AppLifecycleState.paused:
  30. // widget is paused
  31. break;
  32. case AppLifecycleState.detached:
  33. // widget is detached
  34. break;
  35. }
  36. }
  37. @override
  38. Widget build(BuildContext context) => Scaffold();
  39. }
展开查看全部
ryhaxcpt

ryhaxcpt3#

最常见的情况是,如果您有一个动画正在运行,并且您不想在后台消耗资源,则需要执行此操作。在这种情况下,您应该使用TickerProviderStateMixin扩展State,并使用State作为AnimationControllervsync参数。Flutter只会在State可见时调用动画控制器的侦听器。
如果希望在PageRoute被其他内容遮挡时释放PageRoute中的State,可以将falsemaintainState参数传递给PageRoute构造函数。如果这样做,State将在隐藏时重置自身(及其子对象),并且必须使用作为widget的构造函数参数传入的属性在initState中重新构造自身。如果不想完全重置,可以使用模型或控制器类或PageStorage来保存用户的进度信息。
下面是一个示例应用程序,演示了这些概念。

  1. import 'package:flutter/material.dart';
  2. void main() {
  3. runApp(new MaterialApp(
  4. onGenerateRoute: (RouteSettings settings) {
  5. if (settings.name == '/') {
  6. return new MaterialPageRoute<Null>(
  7. settings: settings,
  8. builder: (_) => new MyApp(),
  9. maintainState: false,
  10. );
  11. }
  12. return null;
  13. }
  14. ));
  15. }
  16. class MyApp extends StatefulWidget {
  17. MyAppState createState() => new MyAppState();
  18. }
  19. class MyAppState extends State<MyApp> with TickerProviderStateMixin {
  20. AnimationController _controller;
  21. @override
  22. void initState() {
  23. print("initState was called");
  24. _controller = new AnimationController(vsync: this)
  25. ..repeat(min: 0.0, max: 1.0, period: const Duration(seconds: 1))
  26. ..addListener(() {
  27. print('animation value ${_controller.value}');
  28. });
  29. super.initState();
  30. }
  31. @override
  32. void dispose() {
  33. print("dispose was called");
  34. _controller.dispose();
  35. super.dispose();
  36. }
  37. int _counter = 0;
  38. @override
  39. Widget build(BuildContext context) {
  40. return new Scaffold(
  41. appBar: new AppBar(
  42. title: new Text('home screen')
  43. ),
  44. body: new Center(
  45. child: new RaisedButton(
  46. onPressed: () {
  47. setState(() {
  48. _counter++;
  49. });
  50. },
  51. child: new Text('Button pressed $_counter times'),
  52. ),
  53. ),
  54. floatingActionButton: new FloatingActionButton(
  55. child: new Icon(Icons.remove_red_eye),
  56. onPressed: () {
  57. Navigator.push(context, new MaterialPageRoute(
  58. builder: (BuildContext context) {
  59. return new MySecondPage(counter: _counter);
  60. },
  61. ));
  62. },
  63. ),
  64. );
  65. }
  66. }
  67. class MySecondPage extends StatelessWidget {
  68. MySecondPage({ this.counter });
  69. final int counter;
  70. Widget build(BuildContext context) {
  71. return new Scaffold(
  72. appBar: new AppBar(
  73. title: new Text('Certificate of achievement'),
  74. ),
  75. body: new Column(
  76. crossAxisAlignment: CrossAxisAlignment.stretch,
  77. mainAxisAlignment: MainAxisAlignment.spaceAround,
  78. children: [
  79. new Icon(Icons.developer_mode, size: 200.0),
  80. new Text(
  81. 'Congrats, you clicked $counter times.',
  82. style: Theme.of(context).textTheme.title,
  83. textAlign: TextAlign.center,
  84. ),
  85. new Text(
  86. 'All your progress has now been lost.',
  87. style: Theme.of(context).textTheme.subhead,
  88. textAlign: TextAlign.center,
  89. ),
  90. ],
  91. ),
  92. );
  93. }
  94. }
展开查看全部
relj7zay

relj7zay4#

我有点晚,但来了完美的解决方案,为那些谁可能正在寻找它在未来。Navigator.push()实际上是未来。表示它有then()回调函数。所以then()将在您从第二个屏幕调用Navigator.pop()之后被调用。甚至你可以从第二个屏幕发送一些数据,并在第一个屏幕中访问数据。
举例说明:

  1. //from Screen A
  2. Navigator.of(context).push(MaterialPageRoute(builder:(context)=>B()))
  3. .then((value)=>{ refresh() });
  4. //in Screen B with data
  5. Navigator.pop(context,[1]);
  6. //or without data
  7. Navigator.pop(context);

所以refresh()将在屏幕A的恢复上被调用。

3wabscal

3wabscal5#

我创建visibility_aware_state是为了让它的行为类似于Android的Activity.onResume()。它还考虑了弹出和推送导航。

  1. class Example extends StatefulWidget {
  2. @override
  3. _ExampleState createState() => _ExampleState();
  4. }
  5. class _ExampleState extends VisibilityAwareState<Example> {
  6. @override
  7. Widget build(BuildContext context) {
  8. // return your widget
  9. }
  10. @override
  11. void onVisibilityChanged(WidgetVisibility visibility) {
  12. switch(visibility) {
  13. case WidgetVisibility.VISIBLE:
  14. // Like Android's Activity.onResume()
  15. break;
  16. case WidgetVisibility.INVISIBLE:
  17. // Like Android's Activity.onPause()
  18. break;
  19. case WidgetVisibility.GONE:
  20. // Like Android's Activity.onDestroy()
  21. break;
  22. }
  23. super.onVisibilityChanged(visibility);
  24. }
  25. }
展开查看全部
mbskvtky

mbskvtky6#

Mamnarock您的答案正确但不完整,您共享的链接不可用。
下面是完整的代码:

  1. import 'package:flutter/material.dart';
  2. class YourClass extends StatefulWidget {
  3. @override
  4. _YourClassState createState() => _YourClassState();
  5. }
  6. class _YourClassState extends State<YourClass>
  7. with WidgetsBindingObserver {
  8. @override
  9. void initState() {
  10. super.initState();
  11. WidgetsBinding.instance.addObserver(this);
  12. }
  13. @override
  14. void dispose() {
  15. WidgetsBinding.instance.removeObserver(this);
  16. super.dispose();
  17. }
  18. @override
  19. void didChangeAppLifecycleState(AppLifecycleState state) {
  20. switch (state) {
  21. case AppLifecycleState.resumed:
  22. // Handle this case
  23. break;
  24. case AppLifecycleState.inactive:
  25. // Handle this case
  26. break;
  27. case AppLifecycleState.paused:
  28. // Handle this case
  29. break;
  30. case AppLifecycleState.detached:
  31. // Handle this case
  32. break;
  33. }
  34. }
  35. @override
  36. Widget build(BuildContext context) {
  37. return Container();
  38. }
  39. }

正如TeeTracker在评论中提到的:
这是一个应用程序级别的生命周期,这意味着当整体恢复或不活动或暂停时,而不是单个小部件。

展开查看全部
4zcjmb1e

4zcjmb1e7#

如果您安装了Flutter Hookshttps://pub.dev/packages/flutter_hooks):

  1. @override
  2. Widget build(BuildContext context) {
  3. useOnAppLifecycleStateChange((previous, current) => null);
  4. }

相关问题