参数类型“Function”不能分配给参数类型“void Function()?”在零安全之后
Posted
技术标签:
【中文标题】参数类型“Function”不能分配给参数类型“void Function()?”在零安全之后【英文标题】:The argument type 'Function' can't be assigned to the parameter type 'void Function()?' after null safety 【发布时间】:2021-02-05 13:56:24 【问题描述】:我想实现制作一个带有不同项目的抽屉,所以我为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,
);
有人知道为什么吗?
【问题讨论】:
【参考方案1】:那是因为onPressed
里面的FlatButton
不是一个正常的函数它的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,
);
【讨论】:
不,不是问题还在使用final VoidCallBack onPressed;不过谢谢。 您的代码对我来说运行良好,您的 Flutter 版本是多少?或者你能告诉我你将哪个function
作为参数传递给DrawerItem
我的 Flutter 版本是 1.22.o,我知道它是旧版本,但我必须使用这个版本,因为我在使用 java 时出现错误,并且它不适用于更新版本。
其实你的代码在这里没问题,你能告诉我你作为参数传递的function
的类型吗?
这是完整的代码,然后我希望能够通过构造函数将它传递给另一个文件【参考方案2】:
更改您的代码以接受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,
);
【讨论】:
如果我想要一个带有参数的函数,有什么解决方案吗?例如文本字段函数“onSubmitted”,因为它给我的错误是“参数类型'void Function()?'不能赋值给参数类型'void Function(String)?"。这个错误有什么解决办法吗? @HiteshDanidhariya 是的,您可以简单地将其添加到括号中,即void Function(String myString)
【参考方案3】:
如果您仍然收到此错误“参数onPressed
的值不能为null
,因为它的类型,但隐式默认值为null
。”修改onPressed
函数后,只需应用空安全来解决这样的问题;
final VoidCallback? onPressed;
这适用于Dart 2.x
【讨论】:
【参考方案4】:Dart 2.12(零安全):
代替
final Function? onPressed; // Bad
使用
final void Function()? onPressed; // Good
final VoidCallback? onPressed; // Good
【讨论】:
最终函数()?按下;为我工作,谢谢:) 你能解释一下它背后的逻辑吗?或者给我一些关于这个的链接?谢谢。 @vietstone AFunction
可以是任何东西,例如 Function()
、Function(int)
等,这就是为什么使用 Dart 空安全性,您应该明确告诉 Function
是什么。跨度>
@CopsOnRoad 谢谢你的意见。但我想知道,正如您所说的 Function() 和 Function(int),我认为这是一种多态性,而不是真正的 Null 安全性:D
@vietstone 多态性是另一回事。 Function onPressed
可以被onPressed()
、onPressed(1)
、onPressed(1, true)
调用,所以你可能会遇到运行时错误,但Function() onPressed
只能被onPressed()
调用。这件事与 null 安全性无关,但与 Dart 2.12 无关。【参考方案5】:
使用:
VoidCallback? _onPressed
代替:
VoidCallback _onPressed
这对我有用!
【讨论】:
【参考方案6】:如果您在调用DrawerItem
时发送参数,您还应该像这样向Function
添加一个参数? final void Function(new par) onPressed;
【讨论】:
【参考方案7】: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 */
],
),
));
【讨论】:
【参考方案8】:您可以使用 void Function 代替 Function,您可以像这样指定您的函数类型:
void Function(bool) onPressed;
【讨论】:
【参考方案9】:定义函数时,在关键字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),
));
【讨论】:
【参考方案10】:如果以上解决方案都检查了,那么参考下面的代码
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
【讨论】:
【参考方案11】:使用:
dynamic onPressed;
或
onPressed;
会自动检测或设置参数类型为动态
代替:
VoidCallback onPressed;
【讨论】:
以上是关于参数类型“Function”不能分配给参数类型“void Function()?”在零安全之后的主要内容,如果未能解决你的问题,请参考以下文章
参数类型“Function”不能分配给参数类型“void Function()?”在零安全之后
参数类型“Widget Function(Categoria)”不能分配给参数类型“dynamic Function(Child)”。 (型号)颤振
Flutter中的参数类型'Widget Function(BuildContext)'不能分配给参数类型'Widget Function(BuildContext,Widget)'错误
参数类型“字符串”不能分配给参数类型“对象?函数(对象?,对象?)?
参数类型 'List<Todo>? Function(QuerySnapshot<Object?>)' 不能分配给参数类型 'List<Todo> Function
参数类型“Map<String, dynamic> Function()”不能分配给参数类型“Map<String, dynamic>”