Reputation: 613
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,
),
)
),
],
),
);
}
}
Upvotes: 0
Views: 981
Reputation: 86
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);
Upvotes: 1
Reputation: 408
the setState()
function doesn't pass any arguments to the callback. The code should look like this:
setState(() {
dialogText = value;
});
Upvotes: 2
Reputation: 77304
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.
Upvotes: 1
Reputation: 3455
change this
void _changeDialogText(value){
setState((value){
dialogText = value;
});
}
to
void _changeDialogText(String value){
setState((value){
dialogText = value;
});
}
Upvotes: 0