Flutter 上的小部件的 onResume() 和 onPause() [英] onResume() and onPause() for widgets on Flutter

查看:80
本文介绍了Flutter 上的小部件的 onResume() 和 onPause()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

最常见的情况是,如果您有一个正在运行的动画并且不想在后台消耗资源.在这种情况下,您应该使用 TickerProviderStateMixin 扩展您的 State 并使用您的 State 作为 vsync 参数代码>动画控制器.Flutter 只会在您的 State 可见时负责调用动画控制器的侦听器.

如果您希望 PageRoute 中的 StatePageRoute 被其他内容遮挡时被处理,您可以通过

import 'package:flutter/material.dart';无效主(){运行应用程序(新材料应用程序(onGenerateRoute: (RouteSettings 设置) {if (settings.name == '/') {返回新的 MaterialPageRoute(设置:设置,建造者:(_) =>新的我的应用程序(),维护状态:假,);}返回空;}));}class MyApp 扩展 StatefulWidget {MyAppState createState() =>新的 MyAppState();}类 MyAppState 扩展了 State与 TickerProviderStateMixin {动画控制器_控制器;@覆盖无效的初始化状态(){print("initState 被调用");_controller = new AnimationController(vsync: this)..repeat(min: 0.0, max: 1.0, period: const Duration(seconds: 1))..addListener(() {print('动画值${_controller.value}');});super.initState();}@覆盖无效处置(){打印(处置被调用");_controller.dispose();超级处置();}int_counter = 0;@覆盖小部件构建(BuildContext 上下文){返回新的脚手架(应用栏:新的应用栏(标题:新文本('主屏幕')),身体:新中心(孩子:新的凸起按钮(按下: () {设置状态((){_计数器++;});},孩子:新文本('按钮按下$_counter次数'),),),浮动动作按钮:新的浮动动作按钮(孩子:新图标(Icons.remove_red_eye),按下: () {Navigator.push(context, new MaterialPageRoute(构建器:(BuildContext 上下文){返回新的 MySecondPage(counter: _counter);},));},),);}}class MySecondPage 扩展了 StatelessWidget {MySecondPage({ this.counter });最终的 int 计数器;小部件构建(BuildContext 上下文){返回新的脚手架(应用栏:新的应用栏(title: new Text('成就证书'),),正文:新列(crossAxisAlignment: CrossAxisAlignment.stretch,mainAxisAlignment: MainAxisAlignment.spaceAround,孩子们: [新图标(Icons.developer_mode,大小:200.0),新文本('恭喜,您点击了 $counter 次.',样式:Theme.of(context).textTheme.title,textAlign: TextAlign.center,),新文本('你所有的进步现在都丢失了.',风格:Theme.of(context).textTheme.subhead,textAlign: TextAlign.center,),],),);}}

Right now, a widget only has initeState() that gets triggered the very first time a widget is created, and dispose(), which gets triggered when the widget is destroyed. Is there a method to detect when a widget comes back to the foreground? and when a widget is about to go to the background because another widget just was foregrounded? It's the equivalent of onResume and onPause being triggered for Android, and viewWillAppear and viewWillDisappear for ios

解决方案

The most common case where you'd want to do this is if you have an animation running and you don't want to consume resources in the background. In that case, you should extend your State with TickerProviderStateMixin and use your State as the vsync argument for the AnimationController. Flutter will take care of only calling the animation controller's listeners when your State is visible.

If you want the States that live in your PageRoute to be disposed when the PageRoute is obscured by other content, you can pass a maintainState argument of false to your PageRoute constructor. If you do this, your State will reset itself (and its children) when it's hidden and will have to re-construct itself in initState using the properties passed in as constructor arguments to its widget. You can use a model or controller class, or PageStorage, to hold the user's progress information if you don't want a complete reset.

Here is a sample app that demonstrates these concepts.

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    onGenerateRoute: (RouteSettings settings) {
      if (settings.name == '/') {
        return new MaterialPageRoute<Null>(
          settings: settings,
          builder: (_) => new MyApp(),
          maintainState: false,
        );
      }
      return null;
    }
  ));
}

class MyApp extends StatefulWidget {
  MyAppState createState() => new MyAppState();
}

class MyAppState extends State<MyApp> with TickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    print("initState was called");
    _controller = new AnimationController(vsync: this)
      ..repeat(min: 0.0, max: 1.0, period: const Duration(seconds: 1))
      ..addListener(() {
        print('animation value ${_controller.value}');
      });
    super.initState();
  }

  @override
  void dispose() {
    print("dispose was called");
    _controller.dispose();
    super.dispose();
  }

  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('home screen')
      ),
      body: new Center(
        child: new RaisedButton(
          onPressed: () {
            setState(() {
              _counter++;
            });
          },
          child: new Text('Button pressed $_counter times'),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.remove_red_eye),
        onPressed: () {
          Navigator.push(context, new MaterialPageRoute(
            builder: (BuildContext context) {
              return new MySecondPage(counter: _counter);
            },
          ));
        },
      ),
    );
  }
}

class MySecondPage extends StatelessWidget {
  MySecondPage({ this.counter });

  final int counter;

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Certificate of achievement'),
      ),
      body: new Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          new Icon(Icons.developer_mode, size: 200.0),
          new Text(
            'Congrats, you clicked $counter times.',
            style: Theme.of(context).textTheme.title,
            textAlign: TextAlign.center,
          ),
          new Text(
            'All your progress has now been lost.',
            style: Theme.of(context).textTheme.subhead,
            textAlign: TextAlign.center,
          ),
        ],
      ),
    );
  }
}

这篇关于Flutter 上的小部件的 onResume() 和 onPause()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆