在 null 安全性之后,不能将参数类型“ Function”分配给参数类型“ void Function() ?”

我想实现一个抽屉与不同的项目,所以我创建了一个单独的文件的 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,
);
}
}

有人知道为什么吗?

123341 次浏览

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

final VoidCallBack onPressed;

同时,将一个正常的 function传递给一个 VoidCallBack

跟着官方文件 给你

enter image description 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只是 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 安全性来解决这样的问题;

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;

或者

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

而不是:

VoidCallback onPressed;

更改代码以接受 VoidCallback,而不是 onPress 的 Function。 顺便说一下,VoidCallback 只是 void Function ()的简写,所以您也可以将它定义为 final void Function () onPress;

class TaskCheckBox extends StatelessWidget {
final bool checkBoxState;
**final void Function(bool? a)? onChecked**;


const TaskCheckBox(
this.checkBoxState,
this.onChecked, {
Key? key,
}) : super(key: key);


@override
Widget build(BuildContext context) {
return Checkbox(
activeColor: Colors.lightBlueAccent,
value: checkBoxState,
onChanged: **onChecked**);
}
}

而不是

final Function? onPressed;
使用
final Function()? onPressed; // add parenthesis in Function

Void 函数(bool? a) ? 回调;

检查 void 回调 bool 函数如何工作的屏幕截图 enter image description here

使用:

final void Function()? onTapping;

或者

final voidCallback? onPressed;

有两种可能的解决方案 如果您知道数据类型在省道和空安全

第一名:

加入类型 VoidCallback?

class DrawerItem extends StatelessWidget {
final String text;
final VoidCallback? onPressed;
    

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

第二名:

如果你是一个初学者,并不知道很多关于数据类型,你可以使用动态的,让省道编译器为你处理类型。

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

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