Flutter/Dart: Cast int to double in Widget Param not working - flutter

I'm trying casting a int to double in flutter/dart at param fontSize from Text Widget but I have this exception:
"Another exception was thrown: type 'int' is not a subtype of type 'double' in type cast"
I have been follow the instructions here: Why can't I convert a Number into a Double? but that's not working yet.
here is Text inside my component widget:
class ButtonLogin extends MaterialButton {
ButtonLogin({this.fontSize, ...});
final fontSize;
...
#override
Widget build(BuildContext context){
double fontSizeDouble = (fontSize as num) as double;
...
Text(
label,
style: TextStyle(
fontSize: fontSizeDouble,
color: labelColor,
fontWeight: FontWeight.bold
),
),
...
}
Out from component I'm passing at param fontSize a Int value like this:
...
ButtonLogin(
backgroundColor: ColorsCustom.loginScreenUp,
labelColor: Colors.white,
label: 'Back to other session?',
fontSize: 16,
mOnPressed: () => _login(),
);
...
the ellipsis is just to indicate there is more of code, its not part of code.

I am not getting any error. An advice I can give you to avoid errors is to use data types in your code when you define variables.

Related

Optional IconData on constructor

I'm studying Flutter, so I'm just a newbie.
I tried to create a widget with an optional IconData type parameter in the constructor, but I was getting an error.
I got added "?" in front of the local variable. From then on, I just had to enclose the constructor parameters in "{ }". I've found a way to make it work, but I'm not sure it is the best/correct way to do so.
If you have any tip, I'll be happy to hear it!
That's my code:
class Editor extends StatelessWidget {
final TextEditingController controlador;
final String label;
final String hint;
final IconData? fieldIcon;
Editor(
{required this.controlador,
required this.label,
required this.hint,
this.fieldIcon});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16.0),
child: TextField(
controller: controlador,
style: const TextStyle(
fontSize: 24.0,
),
decoration: InputDecoration(
labelText: label,
hintText: hint,
icon: fieldIcon != null ? Icon(fieldIcon) : null,
),
),
);
}
}
Your code is correct. Nothing inappropriate in my opinion.
However, I feel the following checking for is redundant:
icon: fieldIcon != null ? Icon(fieldIcon) : null,
Given that the icon property of InputDecoration already takes a nullable icon, why not give it just that?
Maybe change the type of fieldIcon from IconData? to Icon? itself. Then, where you consume the icon in the InputDecoration, simply give it the nullable fieldIcon:
icon: fieldIcon,
But wherever you use this Editor widget, remember to give it an Icon for fieldIcon and not an IconData.

Declare variables in build method or in class itself? - Flutter

Which is the correct usage? Also I'm confused about if we should do "extract method" or "extract widget"? Flutter recommends to extract widgets. But I'm not sure where should I extract widget?
class TopBarTitle extends StatelessWidget {
const TopBarTitle();
static const String title = 'FLASHCARDS';
static const String fontFamily = 'Itim';
#override
Widget build(BuildContext context) {
return Text(
title,
style: TextStyle(
fontSize: 18.sp,
color: Theme.of(context).iconTheme.color,
fontWeight: FontWeight.w500,
fontFamily: fontFamily,
),
);
}
}
or
class TopBarTitle extends StatelessWidget {
const TopBarTitle();
#override
Widget build(BuildContext context) {
const String title = 'FLASHCARDS';
const String fontFamily = 'Itim';
return Text(
title,
style: TextStyle(
fontSize: 18.sp,
color: Theme.of(context).iconTheme.color,
fontWeight: FontWeight.w500,
fontFamily: fontFamily,
),
);
}
}
The first one is preferred. build method is supposed to be called many times in a short time and you should keep it simple. In the second code, you're defining two variables every time the method gets called (of course it's a very cheap operation considering they're constant but still it should be prevented whenever possible).
And to answer your question about "extract method" or "extract widget", Flutter recommends "extract widget" since there are lot's optimizations applied in that case and it's easier to debug too. There are lot's of discussions about that which you can easily find by searching. For example read this one: https://stackoverflow.com/a/53234826/5204833
First one is preferred, it will be declare each time you reach to that class
There is problem with the second one each time the set is updating it will will declare those variables again and again

How best to convert old Dart code that triggers "parameter can't be 'null' but the implicit default value is 'null'." error?

Take the following non-null safe Dart code:
class RoundedButton extends StatelessWidget {
RoundedButton({this.title, this.color, #required this.onPressed});
final Color color;
final String title;
final Function onPressed;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
elevation: 5.0,
color: color,
borderRadius: BorderRadius.circular(30.0),
child: MaterialButton(
onPressed: onPressed,
minWidth: 200.0,
height: 42.0,
child: Text(
title,
style: TextStyle(
color: Colors.white,
),
),
),
),
);
}
}
With regards to the constructor's parameters, Android Studio is saying, "The parameter [parameter] can't have a value of 'null' because of its type, but the implicit default value is 'null'."
I understand the error and have discovered that I can simply modify the code like this:
class RoundedButton extends StatelessWidget {
RoundedButton({this.title, this.color, required this.onPressed});
final Color? color;
final String? title;
final Function onPressed;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
elevation: 5.0,
color: color,
borderRadius: BorderRadius.circular(30.0),
child: MaterialButton(
onPressed: onPressed.call(),
minWidth: 200.0,
height: 42.0,
child: Text(
title!,
style: TextStyle(
color: Colors.white,
),
),
),
),
);
}
}
This way, I satisfy the language rules, but using the bang operator to do the "force unwrap" is presumably frowned upon.
So my solution seems hacky... so in this scenario, what is the elegant, proper, or even sexy way to convert this code to null safety, and if there are multiple ways, then what are the pros and cons?
Thanks!
There are several ways to migrate to null safe code, as you said, making all variables nullable is a possible solution, here are two others:
1. Making the variable have a default value
from:
final String title;
to:
final String title = '';
or
MyClass {
MyClass({this.title=''});
final String title;
}
When to use
If you have a variable that should start with some value and change as time goes on or if you have a variable that is unlikely to be unique to each instance.
GOOD
int timesOpened = 0;
BAD
int uniqueValue = 0 // if it should be unique, it shouldn't be default.
2. Forcing a value at the constructor
from:
MyClass {
MyClass({this.title});
final String title;
}
to:
MyClass {
MyClass({required this.title});
final String title;
}
When to use
When you have a value that must be passed to each instance and that is likely to be different for each instance
GOOD
MyClass({required this.onPressed});
BAD
MyClass({required this.textSize}); // probably should have a default text size value
If I were you, I'd make color have a default value and title and onPressed be required parameters. But You'd know better than me.

How to write a function (in flutter-dart) so that it accepts certain parameters when we call that function?

This is my code:
Text ButtonText = Text(
_buttonText, style: TextStyle(
color: Colors.white,
fontFamily: 'San francisco',
//fontSize: 21.0.ssp,
letterSpacing: 2.0,
wordSpacing: 2.0
),
);
when I use this Text in my button widget, I want to set font size explicitly. How can I do that?
you can create a class for your situation we can call it customtext
here is an example code :
import 'package:flutter/material.dart';
class CustomText extends StatelessWidget {
final String text;
final double size;
final Color color;
final FontWeight weight;
// name constructor that has a positional parameters with the text required
// and the other parameters optional
CustomText({#required this.text, this.size,this.color,this.weight});
#override
Widget build(BuildContext context) {
return Text(
text,style: TextStyle(fontSize: size ?? 16, color: color ?? Colors.black, fontWeight: weight ?? FontWeight.normal),
);
}
}

I am trying to pass may multiple data on screen to another screen in flutter but it shows the Invalid argument error

Hello I am trying to pass may multiple data on one screen to another screen in flutter but it shows the Invalid argument error. I couldn't recognize where hav the error.I provide my navigation part code and antoher activity part code.
=>Home Activity navigation part method.
-this is the navigate method.
getItemAndNavigation(BuildContext context){
Navigator.push(context, MaterialPageRoute(builder: (context)=>resultScanner(
scanResult: scannedResult,
resultType: resultType,
)));
}
=> this is my second activity code.
class resultScanner extends StatelessWidget {
final scanResult;
final resultType;
resultScanner({Key key, #required this.scanResult, this.resultType})
: super(key: key);
String currentTime = '';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(
color: Colors.black,
),
title: Text(
"Result",
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Result type = ' + resultType,
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
Text(
'Description = ' + scanResult,
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
],
)),
);
}
}
=>This is the erros showing.
> The following ArgumentError was thrown building resultScanner(dirty,
> state: _resultScannerState#7c9c8): Invalid argument(s)
>
> The relevant error-causing widget was: resultScanner
> file:///F:/Work/QReader/qreader/qreader/lib/screens/homeui.dart:458:34
> When the exception was thrown, this was the stack:
> #0 _StringBase.+ (dart:core-patch/string_patch.dart:267:57)
> #1 _resultScannerState.build (file:///F:/Work/QReader/qreader/qreader/lib/screens/result_scan.dart:46:30)
> #2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4663:28)
> #3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4546:15)
> #4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4719:11)
This is because you have not defined the type, on the second screen.
class resultScanner extends StatelessWidget {
final scanResult;
final resultType;
}
Change it to final String scanResult and final String resultType
Or Maybe whatever you want them to be.
There is another problem with this code in the print Statement:
Text(
'Result type = ' + resulType,
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
It should be:
Text(
'Result type = $resultType'
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
Same goes for scanResult.
I'm a little surprised it compiles at all, but you did not give your variables any type.
So this line is basically having some religious faith in the fact that the variables passed are something that can be concatenated with a plus symbol:
'Result type = ' + resultType,
Give your two variables scanResult and resultType a type (maybe they are strings?) and then figure out whether a simple plus is the right way to concatenate them with another string.