一尘不染

有什么办法可以在Android的Flutter应用中拦截“返回”键按下吗?

flutter

在用户通过Back在Android设备上按按钮离开当前路线之前,我需要显示一个警告对话框。我试图通过WidgetsBindingObserver在小部件状态下实现来拦截后退按钮的行为。GitHub上有一个关于同一主题的封闭问题。但是我的代码不起作用,因为从未调用过didPopRoute()方法。这是我的代码如下:

import 'dart:async';

import 'package:flutter/material.dart';

class NewEntry extends StatefulWidget {
  NewEntry({Key key, this.title}) :super(key: key);

  final String title;

  @override
  State<StatefulWidget> createState() => new _NewEntryState();
}

class _NewEntryState extends State<NewEntry> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  Future<bool> didPopRoute() {
    return showDialog(
      context: context,
      child: new AlertDialog(
        title: new Text('Are you sure?'),
        content: new Text('Unsaved data will be lost.'),
        actions: <Widget>[
          new FlatButton(
            onPressed: () => Navigator.of(context).pop(true),
            child: new Text('No'),
          ),
          new FlatButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: new Text('Yes'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.edit),
        onPressed: () {},
      ),
    );
  }
}

阅读 857

收藏
2020-08-13

共1个答案

一尘不染

我发现解决方案是使用WillPopScope小部件。这是下面的最终代码:

import 'dart:async';

import 'package:flutter/material.dart';

class NewEntry extends StatefulWidget {
  NewEntry({Key key, this.title}) :super(key: key);

  final String title;

  @override
  State<StatefulWidget> createState() => new _NewEntryState();
}

class _NewEntryState extends State<NewEntry> {

  Future<bool> _onWillPop() {
    return showDialog(
      context: context,
      child: new AlertDialog(
        title: new Text('Are you sure?'),
        content: new Text('Unsaved data will be lost.'),
        actions: <Widget>[
          new FlatButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: new Text('No'),
          ),
          new FlatButton(
            onPressed: () => Navigator.of(context).pop(true),
            child: new Text('Yes'),
          ),
        ],
      ),
    ) ?? false;
  }

  @override
  Widget build(BuildContext context) {
    return new WillPopScope(
      onWillPop: _onWillPop,
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text(widget.title),
        ),
        floatingActionButton: new FloatingActionButton(
          child: new Icon(Icons.edit),
          onPressed: () {},
        ),
      ),
    );
  }
}
2020-08-13