空安全后参数类型'Function'不能赋值给参数类型'void Function()?'

The argument type 'Function' can't be assigned to the parameter type 'void Function()?' after null safety

我想制作一个带有不同物品的抽屉,所以我为 DrawerItems 创建了一个单独的文件,并使用构造函数将数据传递到主文件。但是我在 onPressed 函数上收到以下错误:

"The argument type 'Function' can't be assigned to the parameter type 'void Function()'"
class DrawerItem extends StatelessWidget {
    
      final String text;
      final Function onPressed;
    
      const DrawerItem({Key key, this.text, this.onPressed}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return FlatButton(
          child: Text(
            text,
            style: TextStyle(
              fontWeight: FontWeight.w600,
              fontSize: 18.0,
            ),
          ),
          onPressed: onPressed,
        );
      }
    }

有人知道为什么吗?

那是因为 FlatButton 里面的 onPressed 不是一个正常的函数它的 VoidCallBack 函数。 你可以尝试这样的事情:

final VoidCallBack onPressed;

同时,您正在将普通的 function 传递给 VoidCallBack

关注官方文档here

更新代码:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  _myFunction() => print("Being pressed!");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            DrawerItem(
              text: "Hello Jee",
              onPressed: _myFunction,
            ),
          ],
        ),
      ),
    );
  }
}

class DrawerItem extends StatelessWidget {
  final String text;
  final Function onPressed;

  const DrawerItem({Key key, this.text, this.onPressed}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FlatButton(
      child: Text(
        text,
        style: TextStyle(
          fontWeight: FontWeight.w600,
          fontSize: 18.0,
        ),
      ),
      onPressed: onPressed,
    );
  }
}

更改您的代码以接受 VoidCallback 而不是 Function 作为 onPressed
顺便说一句 VoidCallback 只是 shorthand 对于 void Function() 所以你也可以将它定义为 final void Function() onPressed;

更新代码:

class DrawerItem extends StatelessWidget {
    
      final String text;
      final VoidCallback onPressed;
    
      const DrawerItem({Key key, this.text, this.onPressed}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return FlatButton(
          child: Text(
            text,
            style: TextStyle(
              fontWeight: FontWeight.w600,
              fontSize: 18.0,
            ),
          ),
          onPressed: onPressed,
        );
      }
    }

如果您仍然收到此错误“参数 onPressed 由于其类型而不能具有 null 的值,但隐式默认值为 null。”修改 onPressed 函数后,只需应用 null safety 即可解决此问题;

final VoidCallback? onPressed;

这适用于 Dart 2.x

Dart 2.12(空安全):

而不是

final Function? onPressed; // Bad

使用

final void Function()? onPressed; // Good
final VoidCallback? onPressed; // Good

使用:

VoidCallback? _onPressed

而不是:

VoidCallback _onPressed

对我有用!

如果您在调用 DrawerItem 时发送参数,您还应该像这样向 Function 添加一个参数 final void Function(new par) onPressed;

2021:如果你有一个接受多个参数的构造函数,你可能想使用命名参数来避免混淆:

示例:应答按钮小部件

class AnswerButton extends StatelessWidget {
    
      late final Function()? submitAnswer;
    
      Answer({injectMethod}) {
        this.selectHandler = submitAnswer;
      }
    }

主要

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(
        title: Text("App Title"),
      ),
      body: Column(
        children: [
          AnswerButton(injectMethod: _nextQuestion) /* <--- named argument */
        ],
      ),
    ));
  }

您可以使用 void Function 而不是 Function,您可以像这样指定函数的类型:

void Function(bool) onPressed;

 

定义函数时在关键字Function后加上括号()

import 'package:flutter/material.dart';

class Answer extends StatelessWidget {
  final Function() onPressed; //parenthesis () on function
  final String name;
  const Answer(this.name, this.functionMessage, {Key? key}) : super(key: 
key);

  @override
  Widget build(BuildContext context) {
    return Container(
        margin: const EdgeInsets.only(top: 10),
        width: double.infinity,
        child: ElevatedButton(
           style: ElevatedButton.styleFrom(
           primary: Colors.black, // background
           onPrimary: Colors.white, // foreground
          ),
          onPressed: onPressed,
          child: Text(name),
        ));
  }
}

如果以上解决方案均已检查,则参考以下代码

class ManageMenu extends StatelessWidget {
  const ManageMenu(
      {Key? key,
      required this.faIcon,
      required this.text,
      required this.onTapFunction})
      : super(key: key);

  final FaIcon faIcon;
  final String text;
  final Function onTapFunction;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => onTapFunction,
      child: ListTile(
        leading: faIcon,
        title: Text(text),
      ),
    );
  }
}

您可能写错语法 onTap:onTapFunction 而不是 onTap: () => onTapFunction

使用:

dynamic onPressed;

onPressed; 它将自动检测或将参数类型设置为动态

而不是:

VoidCallback onPressed;