空安全后参数类型'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;
我想制作一个带有不同物品的抽屉,所以我为 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;