Flutter provides the setState() method as a method to change the state of any given widget, but sometimes you may wish to update just a specific widget and not rebuild the whole tree. That is where StatefulBuilder comes into play – with it, you can update just one specific widget without rebuilding its entire tree!
In this article, we will cover how to refresh a specific widget using setState and StatefulBuilder in Flutter.
What Is StatefulBuilder?
StatefulBuilder is a Flutter widget that allows you to create widgets with their own mutable state, similar to StatefulWidget but differing in that its setState() method allows only its widget to update.
StatefulBuilder makes using StatefulBuilders easier. Simply wrap your widget with it, and provide a callback function that will be called when its state needs updating. The callback function takes two arguments; they are: BuildContext and StateSetter – these represent the context in which your widget resides wrapped by StatefulBuilders; while StateSetter acts as a way of updating its state directly.
StatefulBuilder to Refresh Widget
If you want to refresh a specific widget, wrap its instance with StatefulBuilder and call its StateSetter function for update of state. Here is an example:
- Define a StatefulWidget: First, create a StatefulWidget that holds the state you want to modify using
StatefulBuilder
. This widget will manage the state and provide a way to update it.
class MyWidget extends StatefulWidget { @override _MyWidgetState createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { int _counter = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('My App'), ), body: Center( child: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Counter: $_counter'), RaisedButton( child: Text('Increment'), onPressed: () { setState(() { _counter++; }); }, ), ], ); }, ), ), ); } }
In this example, _MyWidgetState
holds the state of the widget. The build
method of _MyWidgetState
returns a StatefulBuilder
widget, which wraps the part of the UI that you want to rebuild.
Inside the StatefulBuilder
‘s builder
function, you can access a StateSetter
function, typically named setState
. The setState
function is used to update the state and trigger a rebuild of the wrapped UI.
- Implement the StatefulWidget: Now, you can use
MyWidget
in your app’s widget hierarchy. When the button is pressed, it will call thesetState
function provided byStatefulBuilder
, which updates the state and rebuilds only the specified part of the UI.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyWidget(),
);
}
}
In this example, MyApp
is the root widget of your Flutter app, and it displays the MyWidget
.
Another Example:
import 'package:flutter/material.dart';
void main(){
runApp(MyApp());
}
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
class Home extends StatefulWidget{
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int num1 = 0;
int num2 = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Refresh State of Single Widget"),
backgroundColor: Colors.deepPurpleAccent,
),
body: Container(
padding: EdgeInsets.all(30),
child: Column(
children: [
Container(
child: StatefulBuilder(builder: (context, setState){
return ElevatedButton(
onPressed: (){
setState((){
num1++;
//will refresh content of this StatefulBuilder
});
},
child: Text("Num One - Tow: $num1 - $num2,Increase Number One")
);
})
),
Container(
child: StatefulBuilder(builder: (context, setState){
return ElevatedButton(
onPressed: (){
setState((){
num2++;
//will refresh content of this StatefulBuilder
});
},
child: Text("Num One - Tow: $num1 - $num2,Increase Number Two"));
}),
)
],
),
),
);
}
}
Using StatefulBuilder
with the setState
function allows you to modify the state of the widget and rebuild only the specific part of the UI that needs updating. This can be useful when you want to isolate the rebuilding process to a smaller portion of your widget hierarchy, improving performance and reducing unnecessary rebuilds.