The argument type 'Function?' can't be assigned to the parameter type 'void Function()? - flutter

this is the screenshot of my error code
this code my inputpage:
child: ReusableCard(
onPress: (){
setState(() {
selectGender=Gender.male;
});
},
cardChild: IconContent(icon: FontAwesomeIcons.mars,label: 'Male',),
colour: selectGender==Gender.male? activeCardColor:inactivecolor,
),
and this one other page:onpress function does not work.
class ReusableCard extends StatelessWidget {
ReusableCard({#required this.colour,this.cardChild,this.onPress});
final Color? colour;
final Widget? cardChild;
final Function? onPress;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
child: cardChild,
margin: EdgeInsets.all(15),
decoration: BoxDecoration(
color: colour,
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}
i provide screesshoot for your better understand

Because the widget's onTap is defined as a void Function()? onTap, the value needs to be returned to be used (as a callback). So use:
onTap: ()=> onPress,
You can also define the onPress as a VoidCallback?, then you just need to:
onTap: onPress,

change this line
final Function? onPress;
with
final Function() onPress;

class ReusableCard extends StatelessWidget {
ReusableCard({#required this.colour,this.cardChild,this.onPress});
final Color? colour;
final Widget? cardChild;
final Function? onPress;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress, // the problem is here
child: Container(
child: cardChild,
margin: EdgeInsets.all(15),
decoration: BoxDecoration(
color: colour,
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}
Change this to That:
class ReusableCard extends StatelessWidget {
ReusableCard({#required this.colour,this.cardChild,this.onPress});
final Color? colour;
final Widget? cardChild;
final Function? onPress;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap:(){
--add your on press code here
},
child: Container(
child: cardChild,
margin: EdgeInsets.all(15),
decoration: BoxDecoration(
color: colour,
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}

Just replace like below.
From
onTap: onPress,
To
onTap: () => onPress,
class ReusableCard extends StatelessWidget {
ReusableCard({#required this.colour,this.cardChild,this.onPress});
final Color? colour;
final Widget? cardChild;
final Function? onPress;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onPress,
child: Container(
child: cardChild,
margin: EdgeInsets.all(15),
decoration: BoxDecoration(
color: colour,
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}

I got the same issue, this is the way I solved it:
Instead of
final Function? onPress;
Use this:
final VoidCallback? onPress;

Related

I'm trying to create a optional parameter in constructor but still getting error, can any one help me with that?

class ReusableCard extends StatelessWidget {
ReusableCard({required this.colour, this.cardChild});
final Color colour;
final Widget cardChild;
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(15.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: colour,
),
// child: cardChild,
);
}
}
This is the error :
" The parameter 'cardChild' can't have a value of 'null' because of its type, but the implicit default value is 'null'. "
I don't know what your cardChild code is, but I think the answer you are looking for is this.
class ReusableCard extends StatelessWidget {
final Color colour;
final Widget? cardChild;
ReusableCard({required this.colour, this.cardChild});
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(15.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: colour,
),
child: cardChild ?? SizedBox(),
);
}
}
class ReusableCard extends StatelessWidget {
final Color colour;
final Widget? cardChild; -------> just add ? for making parameter optional
ReusableCard({required this.colour, this.cardChild});
class ReusableCard extends StatelessWidget {
final Color colour;
final Widget cardChild;
//define the variable 1st
//then call the method
ReusableCard({required this.colour, this.cardChild});
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(15.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: colour,
),
// child: cardChild,
);
}
}
class ReusableCard extends StatelessWidget {
final Color colour;
final Widget cardChild;
//define the variable 1st
//then call the method
ReusableCard({required this.colour, this.cardChild});
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(15.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: colour,
),
// child: cardChild,
);
}
}

How do i pass a function as a parameter in dart?

Code down here keeps telling me that there's a problem in the syntax here onTap: onPress,
import 'package:flutter/material.dart';
class ReusableCard extends StatelessWidget {
final Color color;
final Widget? cardChild;
final Function? onPress;
ReusableCard({ this.cardChild, required this.color, this.onPress});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
margin: const EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(15.0),
),
child: cardChild,
),
);
}
}
Use voidcallback
class ReusableCard extends StatelessWidget {
final Color color;
final Widget? cardChild;
final VoidCallback onPress;//here
ReusableCard({ this.cardChild, required this.color, this.onPress});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
margin: const EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(15.0),
),
child: cardChild,
),
);
}
}
or you can also do this
class ReusableCard extends StatelessWidget {
final Color color;
final Widget? cardChild;
final Function? onPress;
ReusableCard({ this.cardChild, required this.color, this.onPress});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){onPress();},//create a method and call onPress here
child: Container(
margin: const EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(15.0),
),
child: cardChild,
),
);
}
}
Function is null type, so it can be null.
You should write
onTap:(onPress!=null) ? onPress : null
Using final Function? onPress; is defined nullable function.
But onTap requires void function,
You can just do
final Function()? onPress;
Or
onTap: () {
if (onPress != null) onPress!();
},
Using VoidCallback
/// Signature of callbacks that have no arguments and return no data.
typedef VoidCallback = void Function();
Hope you get the issue here. Also provide key on constructor.
class ReusableCard extends StatelessWidget {
final Color color;
final Widget? cardChild;
final Function()? onPress;
const ReusableCard({
this.cardChild,
required this.color,
this.onPress,
super.key,
});
But I think it is pretty to use final GestureTapCallback? onPress;

what is the different between Function first class and void function in Dart

in order to optimize my code, I try to use Function first class in the onTap property of the GestureDetector widget, like in the code below:
import 'package:flutter/material.dart';
class ReusableCard extends StatelessWidget {
final Color colour;
final Widget? childCard;
final Function? onPress;
ReusableCard({required this.colour,this.childCard,this.onPress}) ;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
child: childCard,
margin: EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: colour,
borderRadius:BorderRadius.circular(10.0),
),
),
);
}
}
but I got that error: The argument type 'Function?' can't be assigned to the parameter type 'void Function()?'.
hope that someone can explain what going on here and thank you previously.
Use VoidCallback? in this case instead of Function?.
In the end, VoidCallback is defined as typedef VoidCallback = void Function() so you can even end up using Function()? but this is a cool shortcut.
You need to use Function()? instead of Function? as the type of onPress variable because onTap requires a GestureTapCallback which is typedef for a Function().
class ReusableCard extends StatelessWidget {
final Color colour;
final Widget? childCard;
final Function()? onPress;
ReusableCard({required this.colour, this.childCard, this.onPress});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
child: childCard,
margin: EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: colour,
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}

Card Color Not Working Using Gesture Detector Flutter

I am tired of something. I am following a course and I am trying to build a BMI calculator application but the color of the Male-female card does not update when I press it.
I have also used print('Male is selected') and it is showing me in the console that Gender.male or Gender.female is selected but the color is not changing. What am I doing wrong? I am new to flutter. Thanks.
Here is the code
reusable_card.dart
import 'package:flutter/material.dart';
class ReusableCard extends StatelessWidget {
ReusableCard({#required this.colour, this.cardChild, this.onPress});
final Color colour;
final Widget cardChild;
final Function onPress;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
child: cardChild,
margin: EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: Color(0xFF1D1E33),
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}
input_page.dart
Gender selectedGender;
enum Gender {
male,
female,
}
Expanded(
child: ReusableCard(
onPress: () {
setState(() {
selectedGender = Gender.female;
});
},
colour: selectedGender == Gender.female
? kActiveCardColour
: kInactiveCardColour,
cardChild: IconContent(
icon: FontAwesomeIcons.venus,
label: 'FEMALE',
),
),
),
constants.dart
const kActiveCardColour = Color(0xFF1D1E33);
const kInactiveCardColour = Color(0xFF111328);
You have not used the color you are passing :
class ReusableCard extends StatelessWidget {
ReusableCard({#required this.colour, this.cardChild, this.onPress});
final Color colour;
final Widget cardChild;
final Function onPress;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
child: cardChild,
margin: EdgeInsets.all(15.0),
decoration: BoxDecoration(
//pass the colour here
color: Color(0xFF1D1E33),
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}
Your final widget should be like this :
class ReusableCard extends StatelessWidget {
ReusableCard({#required this.colour, this.cardChild, this.onPress});
final Color colour;
final Widget cardChild;
final Function onPress;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
child: cardChild,
margin: EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: colour,
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}

Flutter - How to make a reusable button change its image and color?

I have a button that I can use on multiple different pages. I want to be able to change the image and fill the OutlineButton with a color when it's pressed. How can this be accomplished?
class BackArrowButton extends StatelessWidget {
final Widget child;
final GestureTapCallback onPressed;
BackArrowButton({#required this.onPressed, this.child});
#override
Widget build(BuildContext context) {
return OutlineButton(
padding: const EdgeInsets.all(15.0),
child: child,
borderSide: BorderSide(width: 1.0, color: Color(0xff1A1A1A)),
highlightElevation: 0.0,
highlightedBorderColor: Color(0xFF1A1A1A),
splashColor: Color(0x1F1A1A1A),
shape: CircleBorder(),
onPressed: onPressed,
);
}
This is what I call on multiple pages to show the button.
BackArrowButton(
child: ClipOval(
child: Container(
child: Image.asset(
'assets/images/icons/arrow_back.png',
),
),
),
onPressed: () {
Navigator.pop(context, '/home');
},
),
Make your button a statefullWidget and add setState to the onPress call.
class BackArrowButton extends StatefulWidget {
final Widget child;
final GestureTapCallback onPressed;
BackArrowButton({#required this.onPressed, this.child});
#override
_BackArrowButtonState createState() => _BackArrowButtonState();
}
class _BackArrowButtonState extends State<BackArrowButton> {
#override
void initState() {
_color = Colors.green;
super.initState();
}
Color _color;
#override
Widget build(BuildContext context) {
return OutlineButton(
padding: const EdgeInsets.all(15.0),
child: widget.child,
borderSide: BorderSide(width: 1.0, color: Color(0xff1A1A1A)),
highlightElevation: 0.0,
highlightedBorderColor: _color,
splashColor: Color(0x1F1A1A1A),
shape: CircleBorder(),
onPressed: (){
setState((){
_color = Colors.red;
});
widget.onPressed();
},
);
}
}