Flutter:检测小部件之间的状态转换

时间:2020-03-04 13:22:50

标签: flutter

Flutter 中,有一种方法可以在按下或弹出窗口小部件时检测窗口小部件的背景和前景状态。

例如: 假设有2个小部件A和B。

从小部件A启动小部件B。在这种情况下,将小部件A的状态检测为背景,将小部件B的状态检测为前景。

类似地,当从小部件B向后按下时,应将小部件A的状态检测为前景。

1 个答案:

答案 0 :(得分:0)

作为选择

  1. 创建RouteObserver

  2. 将其分配给MaterialApp navigatorObservers属性

  3. 将RouteAware混合添加到必须观看的每个页面
  4. 覆盖诸如didPush didPopNext ext之类的必要方法
  5. 利润

这是一个完整的示例,我对其进行了简化,因此仅将RouteAware混合添加到了FirstPage

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

void main() => runApp(MyApp());

final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [routeObserver],
      home: Scaffold(
        appBar: AppBar(),
        body: FirstPage(),
      ),
    );
  }
}

class FirstPage extends StatefulWidget {
  @override
  _FirstPageState createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> with RouteAware {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) => routeObserver.subscribe(this, ModalRoute.of(context)));
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: Text('PRESS ME'),
        onPressed: () {
          Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
        },
      ),
    );
  }

  @override
  void didPush() {
    print('didPush FirstPage');
  }

  @override
  void didPopNext() {
    print('didPopNext FirstPage');
  }

  @override
  void didPop() {
    print('didPop FirstPage');
  }

  @override
  void didPushNext() {
    print('didPushNext FirstPage');
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this);
    super.dispose();
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          child: Text('BACK'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

您还可以创建自己的Statefull的类State并从其扩展

另一个完整的示例:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

void main() => runApp(MyApp());

final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [routeObserver],
      home: Scaffold(
        appBar: AppBar(),
        body: FirstPage(),
      ),
    );
  }
}

class FirstPage extends StatefulWidget {
  @override
  _FirstPageState createState() => _FirstPageState();
}

class _FirstPageState extends RouteAwareState<FirstPage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: Text('PRESS ME'),
        onPressed: () {
          Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
        },
      ),
    );
  }
}

class SecondPage extends StatefulWidget {
  @override
  _SecondPageState createState() => _SecondPageState();
}

class _SecondPageState extends RouteAwareState<SecondPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          child: Text('BACK'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

abstract class RouteAwareState<T extends StatefulWidget> extends State<T> with RouteAware {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) => routeObserver.subscribe(this, ModalRoute.of(context)));
  }

  @override
  void didPush() {
    print('didPush $widget');
  }

  @override
  void didPopNext() {
    print('didPopNext $widget');
  }

  @override
  void didPop() {
    print('didPop $widget');
  }

  @override
  void didPushNext() {
    print('didPushNext $widget');
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this);
    super.dispose();
  }
}

当您按下按钮,然后再按下Back按钮时,它将在控制台中打印

I/flutter ( 7188): didPush FirstPage
I/flutter ( 7188): didPushNext FirstPage
I/flutter ( 7188): didPush SecondPage
I/flutter ( 7188): didPopNext FirstPage
I/flutter ( 7188): didPop SecondPage