Flutter: How can I pass values in the constructor so I can reuse my widgets? - flutter

I am quite puzzled about the values being passed in the class constructor not being available in the Widget.
I am passing the value of the cards in the widget constructor, but when debugging it and after they are build the Text widgets do not have any text.
Initializing the Widget with the values.
Debugger shows the cardValue fields with no value.
Empty Widget:

This should work:
class PockerCard extends StatefulWidget {
final String cardValue;
const PockerCard({Key key, this.cardValue}) : super(key: key);
#override
_PockerCardState createState() => _PockerCardState();
}
class _PockerCardState extends State<PockerCard> {
#override
Widget build(BuildContext context) {
return Container(
child: Text(widget.cardValue),
);
}
}

Related

How to set default value of function in a constructor (Flutter)

I want to set default function in my child Widget in a constructor.
Basically, I have two widgets
Login (Parent Widget)
AppButton (Child Widget)
Here is my AppButton.dart
And I am calling this child widget in Login.dart (Parent) like this:
AppButton(title: "Login")
Please give me a way that to set default function without making "onPress" required for it's Parent (Login.dart)
TIA
Only static value can be set as default value in constructor, so you need define you function as static like this:
class AppButton extends StatefulWidget {
final Function onPress;
const AppButton({Key? key, this.onPress = _onPress}) : super(key: key);
static void _onPress(){}
#override
State<AppButton> createState() => _AppButtonState();
}
just make it nullable:
class MyButton extends StatefulWidget {
final void Function()? onPress;
final String title;
const MyButton({Key? key, this.onPress, required this.title}) : super(key: key);
#override
State<MyButton> createState() => _MyButtonState();
}
class _MyButtonState extends State<MyButton> {
void Function() defaultOnPress = (){
// your default function here
};
#override
Widget build(BuildContext context) {
return ElevatedButton(onPressed: widget.onPress ?? defaultOnPress, child: const Text("my button"));
}
}
still you can get const constructor
you could put "static" before childOnPress()

What aspects to consider when defining attributes or methods in a stateful widget?

Below is the definition of a Stateful Widget and its associated state. As we can see, color has been defined in YellowBird and can be accessed in _YellowBirdState via the widget object.
My question is with respect to this, how do we decide where (Widget class or State class) to define the attributes? For example, color could have been defined in _YellowBirdState directly. For now, I am deciding this based on whether I have to access the attributes from outside. For example, considering the example below, if I need to access the attribute color from outside, then I define it in the Widget class.
class YellowBird extends StatefulWidget {
const YellowBird({ Key? key }) : super(key: key);
var color = 0xFFFFE306;
#override
State<YellowBird> createState() => _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
#override
Widget build(BuildContext context) {
return Container(color: Color(widget.color));
}
}
One reason to create the attributes in the widget class is to pass values from outside. In your example you could pass the color dynamically.
class YellowBird extends StatefulWidget {
Color color;
YellowBird(this.color, {Key? key}) : super(key: key);
#override
State<YellowBird> createState() => _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
#override
Widget build(BuildContext context) {
return Container(color: widget.color);
}
}
Now you can create your widget with different colors
YellowBird(Colors.green)
YellowBird(Colors.red)

Difference between passing: method that returns a widget, a unique widget class, or a Widget object

I am confused between these three ways of passing/building widgets:
1.
Widget _myDisplay() {
return [widgets showing content];
}
#override
Widget build(BuildContext context) {
return _myDisplay();
}
#override
Widget build(BuildContext context) {
return MyDisplay();
}
where MyDisplay is defined as such (I'm not sure if it's crucial whether MyDisplay is a StatelessWidget or a StatefulWidget):
class MyDisplay extends StatelessWidget {
const MyDisplay({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return [widgets showing content];
}
}
Widget _myDisplay = [widgets showing content];
#override
Widget build(BuildContext context) {
return _myDisplay;
}
I've read this thread comparing the first two methods, and from what I understand, using a unique, named class extending StatelessWidget or StatefulWidget allows you to use the const keyword which signifies that it will not be rebuilt when the Widget tree is rebuilt.
However, what about the 3rd method above? Is it the same as 1. or 2., or completely different? If so, how is it different and when is it preferred?
Thanks!
Type 1: helper methods
Type 2: Widgets
Type 3: Variables
For type 1 and 2, I will highly recommend to check Widgets vs helper methods | Decoding Flutter
Helper methods will rebuild everything on every state changes which can be heavy based on scenario like using animated-widgets.
Try using Widget with const constructor to get better performance,
Now for the 3rd type variable. It is totally different from helper method and widgets. This variable won't change until you handle the variable state. Test this example code, and you will find the issue where data doesn't change on type3(variable) case.
class Test3 extends StatefulWidget {
const Test3({Key? key}) : super(key: key);
#override
State<Test3> createState() => _Test3State();
}
class _Test3State extends State<Test3> {
String data = "A";
late Widget _myDisplay = Text("$data");
Widget _myDisplayMethod() => Text("$data");
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: () {
setState(() {
data = "b";
});
}),
body: Center(
child: Column(
children: [
_myDisplay, //variables doesn't update state(based on cases)
_myDisplayMethod(),
],
),
),
);
}
}

Flutter Class Properties (basics)

How do you pass properties to a widget class in flutter.
Here is a basic class
class ToolbarToggle extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text(label);
}}
I want to be able to call it
ToolbarToggle(label: 'a label')
Forgive the elementary question.
First you declare a label property, like this:
class ToolbarToggle extends StatelessWidget {
final String label;
#override
Widget build(BuildContext context) {
return Text(label);
}
}
final means the value is immutable, you should add it to every property on a StatelessWidget.
Now we need to declare a Constructor, here is how we do that:
ToolbarToggle(this.label);
This means that when creating a ToolbarToggle, we can do this: ToolbarToggle('some label');. In order to make parameters named, we need to declare the constructor like so:
ToolbarToggle({this.label});
Now it is possible to call ToolbarToggle(label: 'my label');. But this will give an error, because it's possible you don't actually pass any value when calling the constructor. To fix this, you should either make it a required parameter, or give it a default value:
ToolbarToggle({required this.label});
ToolbarToggle({this.label=''});
Here is the final class code:
class ToolbarToggle extends StatelessWidget {
ToolbarToggle({required this.label});
final String label;
#override
Widget build(BuildContext context) {
return Text(label);
}
}
class ToolbarToggle extends StatelessWidget {
final String? label;
const ToolbarToggle({this.label, Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Text(label ?? 'label is null');
}}
Like this, you can pass properties,
Its recommended to use const constructor and a key param ( to uniquely identify incase)
You missed using the label
class ToolbarToggle extends StatelessWidget {
final String label;
ToolbarToggle({required this.label});
#override
Widget build(BuildContext context) {
return Text(label);
}}

Flutter: How to call method of widget's state class from a floating action button

In main, the body of my scaffold is a custom stateful widget. This custom widget has a function inside its state class. Is it possible to call this function from the floating action button in the main file's scaffold?
I don't see how 'wire' the onPressed function of the floating action button to call the function inside the state class of the widget in the scaffold's body.
You can use function callback like this
class Screen extends StatefulWidget {
Screen({Key key}) : super(key: key);
#override
_ScreenState createState() => _ScreenState(methodCaller: myMethod);
String myMethod(int value) {
return 'example';
}
}
class _ScreenState extends State<Screen> {
final String Function(int value) methodCaller;
_ScreenState({this.methodCaller});
#override
Widget build(BuildContext context) {
var value = methodCaller(12);
return Container();
}
}
Hope this is helpful!