带有 AlertDialog 的 Flutter WillPopScope 迁移到 null-safety

Flutter WillPopScope with AlertDialog migration to null-safety

我最近将我的 Flutter 应用程序迁移到空安全,但 WillPopScope 与 AlertDialog 结合使用会导致问题。 WillPopScope 期望 Future<bool>showDialog returns Future<bool?> 我不知道如何将一个转换为另一个。

Widget _buildBody(BuildContext context) {
  return WillPopScope(
    onWillPop: (() => _onBackPressed(context)) as Future<bool> Function(),
    child: new Container([...]),
  );
}

// this should return a Future<bool> but showDialog doesn't allow that
Future<bool?> _onBackPressed(BuildContext context) async {
  if (someCondition) {
    // showDialog returns a Future<T?> 
    return showDialog(
      context: context,
      builder: (context) => new AlertDialog(
        [...]
        actions: <Widget>[
          new TextButton(
            child: Text("cancel",
            onPressed: () => Navigator.of(context).pop(false),
          ),
          new TextButton(
            child: Text("discard",
            onPressed: () => Navigator.of(context).pop(true),
          ),
        ],
    ));
  } else {
    return true;
  }
}

此示例中显示的 onWillPop 中的转换 (() => _onBackPressed(context)) as Future<bool> Function() 无效。

The following _CastError was thrown building Builder(dirty):
type '() => Future<bool?>' is not a subtype of type '() => Future<bool>' in type cast

知道如何捕获 showDialog 返回的 null 值并使 willPopScope 再次快乐吗?

我想最简单的是:

Future<bool> _onBackPressed(BuildContext context) async {
    ...
    return (await showDialog(..)) ?? false // if dialog returns null, return false instead
    ...

bool? dialogResp = await showDialog(...);
if(dialogResp !=) 
   return dialogResp; 
else 
   return false;

Future<bool> _onBackPressed(BuildContext context) async {
    ...
    return showDialog(..).then((x) => x ?? false)
    ...

由于showDialog可以returnnull,我们可以使用??运算符return另一个值当showDialogreturns null。在这种情况下,false:

  Future<bool> _onWillPop() async {
    return (await showDialog(
      context: context,
      builder: (context) => new AlertDialog(),
    )) ?? false;
  }

然后在 WillPopScope 上使用它:

    return WillPopScope(
      onWillPop: _onWillPop,
      child: Scaffold(