flutter navigator2.0 返回键监听

1,956 阅读1分钟

navigator 1.0 使用 WillPopScope 可以监听返回事件,但是在navigator 2.0使用WillPopScope时会失效。碰到这个问题,参考 Add back button listener widget 使用BackButtonListener可以完美解决。

项目介绍

页面OnePage跳转到TwoPage,在TwoPage监听返回事件。

Navigator 1.0 使用WillPopScope监听返回事件。 Navigator 2.0 使用BackButtonListener监听返回事件。

Navigator 1.0 返回监听

关键代码

class TwoPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _TwoPageState();
  }
}

class _TwoPageState extends State<TwoPage> {
  @override
  Widget build(BuildContext context) {
    return PageUtil.buildPage(
        _buildBody(),
        CommonTitleWidget(
          title: "Navigator1.0 Two Page",
          leftClick: () {
            Navigator.pop(context);
          },
        ));
  }

  Widget _buildBody() {
    return WillPopScope(
        child: Center(
          child: Text("This is two"),
        ),
        onWillPop: () {
          return _showDialog();
        });
  }

  Future<bool> _showDialog() async {
    var result = await showDialog<bool>(
      context: context,
      builder: (context) => new AlertDialog(
        title: new Text('Are you sure?'),
        content: new Text('some tip'),
        actions: <Widget>[
          new GestureDetector(
            onTap: () => Navigator.of(context).pop(false),
            child: Text("NO"),
          ),
          SizedBox(height: 16),
          new GestureDetector(
            onTap: () => Navigator.of(context).pop(true),
            child: Text("YES"),
          ),
        ],
      ),
    );
    if (result == true) {
      return Future.value(true);
    } else {
      return Future.value(false);
    }
  }
}

Navigator 2.0 返回监听

关键代码

class _TwoPageState extends State<TwoPage> {
  @override
  Widget build(BuildContext context) {
    return BackButtonListener(
      child: PageUtil.buildPage(
          _buildBody(),
          CommonTitleWidget(
            title: "Navigator 2.0 Two Page",
            leftClick: () {
              AppRouterUtil.popPage(context);
            },
          )),
      onBackButtonPressed: _onBackPressed,
    );
  }

  Widget _buildBody() {
    return Center(
      child: Text("This is two"),
    );
  }

  Future<bool> _onBackPressed() async {
    var result = await showDialog<bool>(
      context: context,
      builder: (context) => new AlertDialog(
        title: new Text('Are you sure?'),
        content: new Text('some tip'),
        actions: <Widget>[
          new GestureDetector(
            onTap: () => Navigator.of(context).pop(false),
            child: Text("NO"),
          ),
          SizedBox(height: 16),
          new GestureDetector(
            onTap: () => Navigator.of(context).pop(true),
            child: Text("YES"),
          ),
        ],
      ),
    );
    if (result == true) {
      return Future.value(false);
    } else {
      return Future.value(true);
    }
  }
}

这里需要注意的是,这里处理的不一样。

  if (result == true) {
      return Future.value(false);
    } else {
      return Future.value(true);
    }

查看BackButtonListener 源码,如果child自已处理事件,则返回true,否则反回false

  /// The callback function that will be called when the back button is pressed.
  ///
  /// It must return a boolean future with true if this child will handle the request;
  /// otherwise, return a boolean future with false.
  final ValueGetter<Future<bool>> onBackButtonPressed;

相关的参考

Add back button listener widget

Learning Flutter’s new navigation and routing system

flutter-navigator-2-0-and-deep-links

示例代码

flutter-dialog-back-button