Flutter StatefulWidget widgets and generics - flutter

How can I pass generic type to the State of a StatefulWidget, Here I want to use my generics in myMethod<T>
class MyWidget<T> extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
#override
Widget build(BuildContext context) {
return Container();
}
myMethod<T>(){
}
}

You just provide the type in your state full widget and then pass it way down to its state:
class MyWidget<T> extends StatefulWidget {
#override
_MyWidgetState<T> createState() => _MyWidgetState<T>();
}
class _MyWidgetState<T> extends State<MyWidget<T>> {
#override
Widget build(BuildContext context) {
return Container();
}
myMethod<T>() {
}
}
Usage:
MyWidget<String>()

_MyWidgetState need to extends State<MyWidget<T>> not just State<MyWidget> and then you can use T within _MyWidgetState

Here's how the Flutter team solves this issue inside the FutureBuilder widget. Instead of having a return type of _MyWidgetState<T> for the createState(), you would need State<MyWidget<T>>.
State<MyWidget<T>> createState() => _MyWidgetState<T>();

Related

Under what situations would it matter whether information is stored in the stateful widget class or the state class?

Here is property as a part of the StatefulWidget class
class MyWidget extends StatefulWidget {
String property = "";
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
#override
Widget build(BuildContext context) {
return Container();
}
}
Here is how I would accessproperty from the State's build method:
widget.property
Here is property as a part of the StatefulWidget's State class
class MyWidget extends StatefulWidget {
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
String property = "";
#override
Widget build(BuildContext context) {
return Container();
}
}
Here is how I would access it from the State's build method:
property
Looks to me like I can achieve the exact same things regardless of whether property is part of the StatefulWidget class or part of the State class.
Am I right or wrong, and if I am wrong, why?

create two pages in flutter project

I am a flutter beginner, I want to create a flutter application that contains two pages, I encounter an error that I do not understand.
Here is my code:
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
class FirstPage extends StatefulWidget {
FirstPage({super.key});
#override
State<MyApp> createState() => _FirstPageState();
}
class _FirstPageState extends State<MyApp> {
String bottonName = 'click';
int currentIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
....
);}}
L'erreur est la suivante:
StatefulWidget.createState must return a subtype of State<FirstPage>
The createState function for FirstPage returned a state of type _FirstPageState, which is not a subtype of State<FirstPage>, violating the contract of createState.
the state type of your First screen is from another widget. change it with this:
class FirstPage extends StatefulWidget {
FirstPage({super.key});
#override
State<FirstPage> createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
String bottonName = 'click';
int currentIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
....
);}} ```

Call setState method in Constructor Error

I want to call method from another class which contains setState. I got some error in page 2like this
This happens when you call setState() on a State object for a widget that hasn't been inserted into the widget tree yet. It is not necessary to call setState() in the constructor, since the state is already assumed to be dirty when it is initially created.
I've read this answer, but I didnt get it on my case. Any Ideas? Thank you
class Page1 extends StatefulWidget {
#override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
#override
void initState(){
Page2().method();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
),
);
}
}
class Page2 extends StatefulWidget {
method() => createState().methodInPage2();
#override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
Future<List<String>> methodInPage2() async{
//error here
setState(){
//setState here,
}
}
#override
Widget build(BuildContext context) => Container();
}

Passing a StatefulWidget as argument and accessing its Constructor

I have created a custom StatefulWidget that takes a Widget as an argument.
import 'package:flutter/material.dart';
class CustomWidget extends StatefulWidget {
final Widget myWidget;
CustomWidget({this.myWidget});
#override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
#override
Widget build(BuildContext context) {
return Container(
child: widget.myWidget(name: 'ASAD'), //I want to achieve this
);
}
}
I'm passing another StatefulWidget named Profile as that argument widget. Now I want to access that passed widget's constructor.
import 'package:flutter/material.dart';
class Profile extends StatefulWidget {
final String name;
Profile({this.name});
#override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
#override
Widget build(BuildContext context) {
return Center(child: Text('${widget.name}'),);
}
}
I'm using the CustomWidget which takes a widget as argument here
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomWidget(myWidget: Profile(),) //I don't want to pass the argument here
);
}
}
I was able to accomplish something like this using typedef but it started throwing an error.
typedef CustomCallBack = Widget Function({String name});
class CustomWidget extends StatefulWidget {
final CustomCallBack myWidget;
CustomWidget({this.myWidget});
#override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
#override
Widget build(BuildContext context) {
return Container(
child: widget.widget(name: 'ASAD'), //I'm able to access the constructor here but now I get an error.
);
}
}
Error
error: The argument type 'Profile' can't be assigned to the parameter type 'Widget Function({String name})'. (argument_type_not_assignable
Note: Based on the app that I'm working on but cannot share code, I have recreated this scenario and is same as far as the issue is concerned.
Try the change this line in the CustomWidget widget,child: widget.widget(name: 'ASAD'), for the widget that you are passing only, without putting the (name: 'ASAD').
So when you pass the Profile Widget, that's when you must specify the value of the name parameter!
body: CustomWidget(myWidget: Profile(name: 'ASAD'),)
please try to use this :
import 'package:flutter/material.dart';
typedef CustomCallBack = Widget Function(String name);
class CustomWidget extends StatefulWidget {
final CustomCallBack myWidget;
CustomWidget({this.myWidget});
#override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
#override
Widget build(BuildContext context) {
return Container(
child: widget.myWidget(
'ASAD'), //I'm able to access the constructor here but now I get an error.
);
}
}
class Profile extends StatefulWidget {
final String name;
Profile({this.name});
#override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
#override
Widget build(BuildContext context) {
return Center(
child: Text('${widget.name}'),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomWidget(
myWidget: (name) => Profile(
name: name,
),
) //I don't want to pass the argument here
);
}
}

How to make custom widget/component in flutter?

Let say I want a container with this style -> rounded shape and with border.
Should I create a theme for Container?
Or should I create my custom widget/component?
My main concern here is not to repeat everything so I'm thinking about this 2 possibilities.
Which one more recommended?
Kind Regards
And why people down voted my question. I really don't know :(
You have to create your widget, which extend Widget
It can be StatelessWidget
class MyWidget extends StatelessWidget {
Widget build(BuildContext context) {
//... return your container here
}
or StatefulWidget
class MyWidget extends StatefulWidget {
MyWidget(this.child);
final Widget child;
#override
State<StatefulWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
#override
Widget build(BuildContext context) {
return Container(child: widget.child, ...)
//... return your container here
}