how to create a constructor in flutter with null safety - flutter

This got a bit tricky for me. since we can no longer pass null values in contructor I had this
class LeadingButton extends StatelessWidget {
final IconData icon;
final Color color;
final Color iconColor;
final double iconSize;
final double size;
final Color backGroundColor;
final VoidCallback onPressed;
final double padding;
final EdgeInsets margin;
final double rotate;
LeadingButton({
#required this.icon,
this.color = Colors.transparent,
#required this.onPressed,
this.size = 20,
this.backGroundColor = Colors.transparent,
this.iconSize = 20,
this.iconColor = darkColor,
this.rotate = 0,
this.padding = 0,
this.margin = const EdgeInsets.all(10)});
...
I am getting an error on icon and onpressed function. although the
documentation is saying
The parameter 'onPressed' & 'icon' can't have a value
of 'null' because of its type, but the implicit default value is
'null'. Try adding either an explicit non-'null' default value or the
'required' modifier.
I guess I am missing some thing, kindly mind to share

Not sure, but it could be that this is due to the recent change of the keyword.
Did you try the required keyword instead?
https://dart.dev/null-safety/faq#how-does-required-compare-to-the-new-required-keyword

I think that LeadingButton's onPressed type needs to be changed to VoidCallback? so it can accept null values.

Related

The parameter 'buttonText' can't have a value of 'null' because of its type 'String', but the implicit default value is 'null'

I am trying to compile a calculator app, from a flutter template. I'm getting this error.
lib/buttons.dart:13:46: Error: The parameter 'buttonText' can't have a value of 'null'
because of its type 'String', but the implicit default value is 'null'.
Try adding either an explicit non-'null' default value or the 'required' modifier.
MyButton({this.color, this.textColor, this.buttonText, this.buttontapped});
^^^^^^^^^^
So now I'm trying to add a value for the button text, but I'm having issues. This is what I tried, the last line is what I added, the rest were there before.
// declaring variables
final color;
final textColor;
final String buttonText;
final buttontapped;
buttonText = Whatever,
You need to add the required statement to your class contstructor.
//Constructor
MyButton({this.color, this.textColor, required this.buttonText, this.buttontapped})
Or provide your default value.
//Constructor
MyButton({this.color, this.textColor, this.buttonText = 'what ever', this.buttontapped})
Or make your field optional, I don't think you want this!
final color;
final textColor;
String? buttonText;
final buttonTapped;
buttonText is a string so Whatever needs to be wrapped in ''
ie
final color;
final textColor;
final buttonText;
final buttonTapped;
then
myButton({this.buttonText = 'whatever'})
or dont declare it at all until it is used
myButton({required this.buttonText})
and remove the separate declaration of it.

How to make widget without '?' and 'required'

so im working on company project and realize the widget doesn't need Key? and required costructor, and when i try to make it like that it occur red underline.
my project i want to remove the required and '?'
example of what i want
It should view like that:
class CustomButton extends StatelessWidget {
final double? height;
final double width;
final String title;
final double margin;
final Function() onPressed;
const CustomButton ({
Key? key,
this.height,
required this.width,
required this.title,
required this.margin,
required this.onPressed,
}) : super (key: key);
}
If you want to preserve the non-nullable state of your class, you have to pass an initial value for the CustomButton height property.
class CustomButton extends StatelessWidget {
final double height;
final double width;
final String title;
final double margin;
final Function() onPressed;
const CustomButton ({
Key? key,
this.height = 100,
required this.width,
required this.title,
required this.margin,
required this.onPressed,
}) : super (key: key);
}
you have probably defined height as final and that's why it is asking it.
define height as
double? height

Flutter: create const color from hex string

I am using Firebase remote config to store my color values. This gives me the flexibilty to update colors without the need to update my app. Now I have written myself a helper function which returns the color object.
In my Firebase remote config I have stored the hex color codes as strings. However, now I am facing the problem that my colors are no constants (const). This is a huge problem for me as I have set default color values in some constructors like here:
const CustomIcon(
{required this.iconType,
this.size,
this.color = Helper.getColor("black"),
Key? key})
: super(key: key);
Because my color is not a const value anymore I get the following error: https://dart.dev/tools/diagnostic-messages#non_constant_default_value
This is my helper function:
static Color getColor(colorName) {
final remoteConfig = FirebaseRemoteConfig.instance;
String colorString = remoteConfig.getString(colorName);
const color = Color(int.parse(colorString));
return color;
}
Do you have any idea on how I can solve this problem?
Kind regards
You sadly won't be able to const anything from the API. The const keyword implies that the Dart Analyzer knows what the value will be even before compiling. This isn't the case here, as the values come from the API.
However, you can still have a solution, by using a local Color default value, and checking for a null color.
class CustomIcon extends StatelessWidget {
final String iconType;
final int? size;
final Color? color;
late final Color defaultColor = Helper.getColor("black");
CustomIcon({required this.iconType, this.size, this.color, Key? key})
: super(key: key);
#override
Widget build(BuildContext context) {
final _color = color ?? defaultColor;
// Build your Widget
return Container(
color: _color,
height: 50,
width: 50,
);
}
}
Here is a simple DartPad showing it in action: https://dartpad.dev/?id=562c943972abaefd29b7b264e16ad5aa

how to make a non required parameter in dart

I have different required parameters in flutter and I want to make one of them non required (colour). If I leave it without the required key, it give an error. How can I make it? Here is my code:
class DiscoverCardTemplate extends StatelessWidget {
DiscoverCardTemplate({
required this.textTop,
required this.textMiddle,
required this.textBottom,
required this.coverImage,
required this.onTap,
this.colour,
});
final String textTop, textMiddle, textBottom, coverImage;
final Function onTap;
final Color colour;
make it nullable means colour will be either null or colur_value.
class DiscoverCardTemplate extends StatelessWidget {
DiscoverCardTemplate({
required this.textTop,
required this.textMiddle,
required this.textBottom,
required this.coverImage,
required this.onTap,
this.colour,
});
final String textTop, textMiddle, textBottom, coverImage;
final Function onTap;
final Color? colour;
or
add a default value for colour (if you didn't pass colour then it uses default value).
class DiscoverCardTemplate extends StatelessWidget {
DiscoverCardTemplate({
required this.textTop,
required this.textMiddle,
required this.textBottom,
required this.coverImage,
required this.onTap,
this.colour = colour_value,
});
final String textTop, textMiddle, textBottom, coverImage;
final Function onTap;
final Color colour;
Either make the
final Color colour;
as nullable:
final Color? colour;
Or, assign a default color in the constructor
this.colour = Colors.black,

Flutter: add a simple wrapper to the Text widget

I came from a React world and trying to get my head around Flutter and Dart.
I'm using the Text widget with the same parameters a lot, so it seems reasonable to think of a way to reuse code. I created a wrapper that uses it:
import 'package:flutter/material.dart';
TextStyle getThemeProperty(type, TextTheme textTheme) {
switch (type) {
case 'headline1':
return textTheme.headline1;
case 'headline2':
return textTheme.headline2;
case 'headline3':
return textTheme.headline3;
default:
return textTheme.bodyText2;
}
}
class CustomText extends StatelessWidget {
const CustomText({Key key, this.type, this.text, this.color}) : super(key: key);
final type;
final text;
final color;
#override
Widget build(BuildContext context) {
var textTheme = Theme.of(context).textTheme;
var style = getThemeProperty(type, textTheme);
if (this.color != null) style.color = this.color;
return Text(
this.text,
style: style,
);
}
}
// Usage
CustomText(
text: 'Some Heading',
type: 'headline2',
color: Colors.black
)
The idea is to set the color if the color property is passed as a parameter, but Dart's compiler doesn't like it. It throws me the error: ''color' can't be used as a setter because it's final.
Try finding a different setter, or making 'color' non-final.'
I'm planning to do the same to fontWeight and textAlign properties as well. How am I able to make this work, I mean, to add new props to the style object on demand?
The reason why the dart compiler is unhappy is just because the color property of the TextStyle is declared as final. Therefore to use a new color, you have to create a new instance of the TextStyle.
Luckily, the TextStyle class comes with a copyWith method that returns an edited copy of your TextStyle
final type;
final text;
final color;
#override
Widget build(BuildContext context) {
var textTheme = Theme.of(context).textTheme;
var style = getThemeProperty(type, textTheme);
return Text(
this.text,
// Added this...
style: style.copyWith(color: color ?? style.color),
);
}
As a side note, when making reusable widgets, it's always a good idea to type your parameters. This is because any type of variable can be used. So instead of passing a String for text, you may pass an int
// DON'T DO THIS
final type;
final text;
final color;
// DO THIS
final String type;
final String text;
final Color color;
Also adding the this keyword to reference a variable in a class without variable shadowing is unnecessary.
// DON'T
this.text
// DO
text