Reputation: 2731
I just started flutter, this is a basic question but I am not able to solve. I created a stateful widget and I need to call the setState() method on click of a button. The button is not part of this stateful widget. The button is present in the footer of application.
complete application code:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
build(BuildContext context) {
return new MaterialApp(
title: "My app title",
home: new Scaffold(
appBar: new AppBar(
title: new Text("My App"),
backgroundColor: Colors.amber,
),
body: new Container(
child: new Center(
child: new MyStateFullWidget(),
),
),
persistentFooterButtons: <Widget>[
new FlatButton(
onPressed: () {
// I need to call the update() of MyStateFullWidget/MyStateFullWidgetState class
},
child: new Text("Click Here"),
color: Colors.amber,
textColor: Colors.white,
),
],
));
}
}
class MyStateFullWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyStateFullWidgetState();
}
}
class MyStateFullWidgetState extends State<MyStateFullWidget> {
int count = 0;
@override
Widget build(BuildContext context) {
return new Text("Count: $count");
}
update() {
setState() {
count++;
}
}
}
Upvotes: 2
Views: 10268
Reputation: 267404
You should use your Scaffold
in the State
instead of using in StatelessWidget
.
Here is the working solution.
class MyApp extends StatelessWidget {
@override
build(BuildContext context) {
return MaterialApp(
title: "My app title",
home: MyStateFullWidget());
}
}
class MyStateFullWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return MyStateFullWidgetState();
}
}
class MyStateFullWidgetState extends State<MyStateFullWidget> {
int count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("My App"),
backgroundColor: Colors.amber,
),
body: Container(
child: Center(
child:Text("Count: $count"),
),
),
persistentFooterButtons: <Widget>[
FlatButton(
onPressed: update,
child: Text("Click Here"),
color: Colors.amber,
textColor: Colors.white,
),
],
);
}
void update() {
setState(() {
count++;
});
}
}
Upvotes: -1
Reputation: 17799
I need to call the setState() method on click of a button
You may have a few options (or alternatives) to achieve the end result (all with different tradeoffs):
count
) to an Inherited Widget above the Button and Display Widget. This may be the easiest or most appropriate.dispatch
an action, which affects the display widget via a StoreConnector
and rebuilds). This can be seen as just another way to 'elevate' state. However, this requires a whole new dependency and a lot of overhead given your simple example, but I wanted to point it out.There may be other solutions that I'm not thinking of; however, remember that the goal of reactive UI is to keep state simple.
So if you have multiple leaf widgets that care about a piece of state (want to know it, want to change it), it might mean that this belongs to a higher level component (e.g a App-level piece of state, or maybe some other common ancestor - but both could use Inherited Widget to prevent passing the piece of state all around)
Upvotes: 6