简体   繁体   中英

Flutter WillPopScope with AlertDialog migration to null-safety

I have recently migrated my Flutter app to null-safety but WillPopScope in combination with AlertDialog causes a problem. WillPopScope expects Future<bool> but showDialog returns Future<bool?> and I can't figure out how to cast one onto the other.

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;
  }
}

The cast (() => _onBackPressed(context)) as Future<bool> Function() in onWillPop as shown in this sample is not working.

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

Any idea how I can catch the null value returned by showDialog and make willPopScope happy again?

I guess easiest would be:

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

or

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

or

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

Since showDialog can return null , we can use a ?? operator to return another value when showDialog returns null . In this case, false :

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

Then use this on WillPopScope :

    return WillPopScope(
      onWillPop: _onWillPop,
      child: Scaffold(

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM