I have a situation where I want to create multiple flutter StatefulWidgets based on the same state class. The problem I run into seems clear, the state widget needs to know the properties of the parent that calls createState. There has to be a way to accomplish this without having to copy paste large amounts of code.
What I have so far is a state class that looks like this:
abstract class XxxState<T extends StatefulWidget> extends State<T>
{ TextEditingController textController; // instantiated by initState().
}
to accomplish what I want I create several abstract methods that the subclass will override to implement it's function. The problem is when I create the class I want to instantiate I don't know how to connect the new StatelessWidget to the state class that overrides the XxxState class.
class YyyWidget extends StatefulWidget {
#override
_YyyState createState() => _YyyState();
}
class _YyyState<YyyWidget> extends XxxState {
/// In this class widget.xxx looks to StatefulWidget and not YyyWidget
}
Any reference for how this should be done would be appreciated.
All one has to do is learn how to subclass a StatefulWidget correctly and all works as expected.
abstract class YyyWidget extends StatefulWidget { ... }
// Do not do the createState here
// Someone edited the question and removed the abstract from the code,
// thereby changing the question to one they thought they could answer.
Then create the abstract state
abstract class YyyState<Page extends XxxWidget>
extends State<Page> {
{
TextEditingController textController;
...
}
Then the subclass calls
class ZzzWidget extends XxxWidget {
// Do the create state here
#override
_AaaState createState() => _AaaState();
}
and the subclass state is
class _AaaState extends YyyState<AaaWidget> {
//inside this class widget.field gets state from AaaWidget
}
I don't even remember what the original post was, So maybe deleting the question is the better option here.
Related
createState:
Creates the mutable state for this widget at a given location in the tree.
https://api.flutter.dev/flutter/widgets/StatefulWidget/createState.html
Now, in code:
class A extends StatefulWidget {
#override
_AState createState() => _AState();
}
class _AState extends State<A> {
}
Here we create a separate class named _AState which inherits from a predefined class named State?
So, what is createState' role here? How does it create a mutable state for us?
With createState you tell the StatefulWidget which class to use as state for this widget. And you tell it here that it needs to create an instance of _AState for this widget.
By the way, it is also recommended to write it as
State<A> createState() => _AState();
It still works the way you wrote it but the IDE might complain about
Avoid using private types in public APIs
Saying the return type is State<A> instead of _AState removes this warning.
In order to create a stateful widget in a flutter, it uses the createState() method. Stateful Widget means a widget that has a mutable state.
I have a class which has variables like this:
class MyDragTarget extends StatefulWidget {
final String assetImage;
final String name;
MyDragTarget(this.name, this.assetImage);
}
EDIT: Sorry for wrong code below. I knew how to use widget.name to get name of the parent. But how can i get name of other class.
Should i use InheritedWidget? To use InheritedWidget must i learn Provider?
I want to access the name and assetImage of MyDragTarget in another class such as:
class Another extends StatefulWidget {
print(MyDragTarget.name);
}
You can use widget.name. For example, if you are trying to access assetImage you can use print('${widget.assetImage}'); Just a side note, this is to access the variables in your StatefulWidget. You can't do it for any class.
you can get using widget
widget.assetImage
wiget.name
print('${wiget.name}');
if you want to use in its create State class, you can access it via widget.assetImage Like
class _MyDragPlayerState extends State<MyDragPlayer> {
...
// print('${widget.assetImage }');
...
}
but if you want to access in other classes than this you can declare variables as static like
class MyDragTarget extends StatefulWidget {
static String assetImage;
static String name;
MyDragTarget(this.name, this.assetImage);
#override
_MyDragTargetState createState() => _MyDragTargetState();
}
and then in other class you can access via
class OtherClass{
...
// print('${MyDragTarget.assetImage }');
...
}
check for null safety first, also read about pros and cons of using static variables.
I have StatefulWidget instance.
However I want to access the method of State from the instance of StatefulWidget.
It might be very simple and basic for flutter, but for the beginner of Stateful/State systen, it is a bit complex.
class MainBody extends StatefulWidget{
#override
_MainBodyState createState() => _MainBodyState();
}
class _MainBodyState extends State<MainBody>{
_MainBodyState();
void connectMainBody(){
print("ConnectMainBody");
}
class _MyHomePageState extends State<MyHomePage> {
Widget mainBody;
#override
void initState() {
super.initState();
mainBody = new MainBody();
mainBody.connectMainBody()// how can I access this method??
}
My idea was completely wrong.
https://medium.com/flutter-community/flutter-communication-between-widgets-f5590230df1e
I checked this page and learned.
How to access from Parent to Child.
By giving parameters to Child's Constructor.
How to access from Child to Parent.
By using callback function given to Child from Parent in advance.
I think I should learn about GlobalKey next.
Thank you very much for your advice.
I'm currently learning Flutter. I tried to deep dive into Flutter Widget life-cycle, and I wonder why StatefulWidget are written like this :
class Example extends StatefulWidget {
#override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
// initState
// setState
// ...
#override
Widget build(BuildContext build) {
...
}
}
but not :
class Example extends StatefulWidget {
// initState
// setState
// ...
#override
Widget build(BuildContext build) {
...
}
}
I think the latter makes the source simple. But I don't know why they're using the former style ?
The reason why StatefulWidget uses a separate State class and not having build method inside its body is because all fields inside a Widget are immutable, and this includes all its sub-classes.
You might have noticed that StatelessWidget has its build and other associated methods defined inside it, but that was possible due to the nature of StatelessWidget which is rendered completely using the provided info, and doesn't expect any future change in its State.
In the case of StatefulWidget, State information occasionally change (or expected to change) during the course of the app, thus this information isn't suitable for storage in a final field (build) to satisfy Widget class conditions (all fields are immutable). That's why State class is introduced. You just have to override the createState function to attach your defined State to your StatefulWidget, and let all that change happens in a separate class.
I keep primitive states inside State. But for objects, the following works:
class _Like extends StatefulWidget {
final Post _post; <-- mutable object is here
_Like(this._post);
#override
State<StatefulWidget> createState() => _LikeState();
}
class _LikeState extends State<_Like> {
...
_like() {
setState(() {
widget._post.liked = !widget._post.liked; <-- mutated here
});
}
...
}
What would the be reason not to use this approach? (As opposed to moving the state inside State, preferably as primitive bool)
Perhaps because initState() is in the State class, which your StatefulWidget can't call. So your entire state should be in your State class to permit that.