How to change a State of a StatefulWidget inside a StatelessWidget?
7,207
Solution 1
I have approached this problem by initializing the _TestTextState as the final property of the TestText widget which allows to simply update the state when the change button is pressed. It seems like a simple solution but I'm not sure whether it's a good practice.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Test app',
home: new Scaffold(
appBar: new AppBar(
title: new Text("Test"),
),
body: new Test(),
),
);
}
}
class Test extends StatelessWidget {
final _TestText text = new _TestText();
@override
Widget build(BuildContext context) {
return new Column(
children: [
text,
new RaisedButton(
child: new Text("change"),
onPressed: () => text.update(),
),
]
);
}
}
class TestText extends StatefulWidget {
final _TestTextState state = new _TestTextState();
void update() {
state.change();
}
@override
_TestTextState createState() => state;
}
class _TestTextState extends State<TestText> {
String text = "original";
void change() {
setState(() {
this.text = this.text == "original" ? "changed" : "original";
});
}
@override
Widget build(BuildContext context) {
return new Text(this.text);
}
}
Solution 2
thier is no way to do so. any how you have to convert your StatelessWidget to StatefulWidget.
Author by
Jakub
Updated on December 07, 2022Comments
-
Jakub over 1 year
Just testing out flutter. The code sample below is a very simple flutter app. The problem is that I don't know how to call the setState() function inside the TestTextState class in order to change the text each time when the change button is pressed.
import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'Test app', home: new Scaffold( appBar: new AppBar( title: new Text("Test"), ), body: new Test(), ), ); } } class Test extends StatelessWidget { final TestText testText = new TestText(); void change() { testText.text == "original" ? testText.set("changed") : testText.set("original"); } @override Widget build(BuildContext context) { return new Column( children: [ testText, new RaisedButton( child: new Text("change"), onPressed: () => change(), ), ] ); } } class TestText extends StatefulWidget { String text = "original"; void set(String str) { this.text = str; } @override TestTextState createState() => new TestTextState(); } class TestTextState extends State<TestText> { @override Widget build(BuildContext context) { return new Text(this.widget.text); } }
-
Jakub over 5 yearsThanks for the super fast response. Adding the StreamController seems like a good idea. How the solution with no non-final field would look like? Is that even possible?
-
Jakub over 5 yearsThanks for your replay. So if I have several different pages in my app and all of them share the one dynamic text widget, does it mean that I have to convert all my screens to StatefulWidgets? How would it reflect the performance?
-
Andrey Turkovsky over 5 yearsStore this field inside
TestTextState
, and insidelisten
check current value oftext
- for example. In this case you can send any data to stream - type doesn't matter