I'm getting a warning that The argument type 'void Function(dynamic)' can't be assigned to the parameter type 'void Function()' which is line right below the String dialogText. I used this function to pass data from Child widget, TopAppBar, to Parent widget which is MyApp. From the child widget, TopAppBar, I used TextFormField to type the word to change the text when it's submitted.
I saw the other codes that have no problem, so I don't know how to solve this problem.
Please help me! Thank you!
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int count = 0;
var nameList = ['one','two','three','four'];
String dialogText = "Hello!";
void _changeDialogText(value){
setState((value){
dialogText = value;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: TopAppBar(state: _changeDialogText,),
body: Column(
children: [
Container(
height: 400,
child: (
ListView(
children: List.generate(
nameList.length, (index) => CustomListTile(title: nameList[index])),
)
)
),
Container(
height: 20, child: Text(count.toString())
),
Container(
height: 20, child: Text(dialogText)
),
],
),
floatingActionButton: FloatingActionButton(
child: Text('Button'),
onPressed: (){
print('a');
setState(
(){
count ;
}
);
},
),
bottomNavigationBar: BottomBar(),
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked
);
}
}
class TopAppBar extends StatefulWidget with PreferredSizeWidget{
const TopAppBar({Key? key, required this.state(value)}) : super(key: key);
final Function(String value) state;
@override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
State<TopAppBar> createState() => _TopAppBarState();
}
class _TopAppBarState extends State<TopAppBar> {
final TopAppBarData _topAppBarData = TopAppBarData();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Form(
child:
AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: <Color>[Color.fromRGBO(180, 44, 77, 1) , Color.fromRGBO(242, 114, 59, 1)]
)
),
),
elevation: 0.0,
centerTitle: false,
title: Row(
children: [
Text(
'SSG',
style: TextStyle(
color: Colors.white,
),
),
Icon(
Icons.expand_more,
color: Colors.black,
)
],
),
actions: [
Padding(
padding: EdgeInsets.only(right: 30.0),
child: IconButton(
icon: Icon(Icons.search),
color: Colors.black,
onPressed: (){
showDialog(context: context, builder: (context){
return AlertDialog(
title: Text('Search'),
content: TextFormField(
onChanged: (value) {
widget.state(value);
},
decoration: InputDecoration(hintText: "Text Field in Dialog"),
),
actions: <Widget>[
ElevatedButton(
child: Text('CANCEL'),
onPressed: () {
setState(() {
Navigator.pop(context);
});
},
),
ElevatedButton(
child: Text('OK'),
onPressed: () {
setState(() {
Navigator.pop(context);
});
},
),
],
);
});
},
)
),
Padding(
padding: EdgeInsets.only(right: 30.0),
child: GestureDetector(
onTap: () {},
child: Icon(
Icons.menu,
color: Colors.black,
),
)
),
Padding(
padding: EdgeInsets.only(right: 30.0),
child: GestureDetector(
onTap: () {},
child: Icon(
Icons.notification_add,
color: Colors.black,
),
)
),
],
),
);
}
}
CodePudding user response:
the setState()
function doesn't pass any arguments to the callback. The code should look like this:
setState(() {
dialogText = value;
});
CodePudding user response:
change this
void _changeDialogText(value){
setState((value){
dialogText = value;
});
}
to
void _changeDialogText(String value){
setState((value){
dialogText = value;
});
}
CodePudding user response:
If you omit types, dynamic
is assumed by the compiler. Don't do that. Turn on your linter (it should be on by default) and it will warn you about it.
final /* --> */ void /* <-- */ Function(String value) state;
and
void _changeDialogText( /* --> */ String /* <-- */ value){
Now, the signatures match.
CodePudding user response:
Your problem stems from how you're setting your state. The setState
function takes an argument of void Function()
as seen below:
package:flutter/src/widgets/framework.dart
void setState(void Function() fn)
Containing class: State Type: void Function(void Function())
However, you add an unnecessary argument value
of type dynamic
.
Changing
void _changeDialogText(value){
setState((value){
dialogText = value;
});
}
to
void _changeDialogText(String value){
setState((){
dialogText = value;
});
}
will get rid of that warning. But you may want to consider using explicit types and force that by adding implicit-dynamic to your analysis options file.
Also, when initializing your final Function(String value) state;
variable in the constructor, you use:
const TopAppBar({Key? key, required this.state(value)}) : super(key: key);
However, this is unnecessary and is missing a type on the "value" parameter. so you may use this instead:
const TopAppBar({Key? key, required this.state}) : super(key: key);