The better way to create stateful widgets in flutter

Building Apps🛠️🔥 with Flutter🚀
Search for a command to run...

Building Apps🛠️🔥 with Flutter🚀
No comments yet. Be the first to comment.
Learn how to use and manage assets easily and without hassle. Introduction, If you are a developer, you know what I am talking about. Assets are any fonts, icons, images, or files that are used inside the app. When the app gets large and assets will ...
Learn to use extension method in your next flutter app

Learn the folder Structure for flutter project best suited for Team Environment.

Well, since you have come here, I can guess you are looking for some improvements in your coding and code quality. That's great!
Let's take a look at it how we can do it better :
While using the stateful widgets we need to be mindful of rebuilding the widget tree which significantly impacts the performance of your application. Here we will look at an example ( there can be many ways to achieve the same thing). In this example, we will make use of ValueNotifier and ValueListenableBuilder
flutter create example_app
Now, we are done setting up the Flutter app, let's dive into the example.
In my main.dart file,
import 'package:flutter/material.dart';
void main() async {
runApp( const MainApp()); // entry point of your application
}
// In this example, we have a stateless widget
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: MySwitch() // MySwitch() is a stateful widget
),
),
);
}
}
ValueNotifier is a class that has a single generic type ( which means it can't hold more than one value) that specifies the type of value it holds. When the value it holds is changed it will trigger all the listeners listening to the changed value.
ValueNotifier<bool> switchValue = ValueNotifier<bool>(false);
Here I have created a ValueNotifier that stores a boolean value that has an initial value of false.
We can use this ValueNotifier which in this case is switchValue to listen to the value and trigger the change of value to different available listeners.
ValueListenableBuilder is a widget that can listen and update the UI based on the value.
ValueListenableBuilder<bool>(
// valueListenable accepts the valueNotifier we have just created
valueListenable: switchValue,
// builder gives the current context, current value and the child it has to return
builder: (BuildContext context, bool value, Widget? child) {
return Switch(
// switch takes the boolean value which is returned by builder method
value: value,
onChanged: (newValue) {
// onChanged return the value opposite to current value. eg
// if the current value is false, it will return true
// Now we access the value inside of valueNotifier and change it with the value we got from onChanged Method
switchValue.value = newValue;
/// when this value changed the builder method is re-run
},
);
},
);
Now that we understand how it works, let's wrap it up, in a line.
ValueListenableBuilder listens to the ValueNotifier that has a single generic value, on change of which ValueListenableBuilder will re-run the builder method, which reflects the change in UI without rebuilding the whole widget tree.
Full Code:
import 'package:flutter/material.dart';
void main() async {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(child: MySwitch()),
),
);
}
}
class MySwitch extends StatefulWidget {
@override
_MySwitchState createState() => _MySwitchState();
}
class _MySwitchState extends State<MySwitch> {
ValueNotifier<bool> switchValue = ValueNotifier<bool>(false);
@override
void dispose() {
switchValue.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
print("Widget rebuilding");
return ValueListenableBuilder<bool>(
valueListenable: switchValue,
builder: (BuildContext context, bool value, Widget? child) {
return Switch(
value: value,
onChanged: (newValue) {
switchValue.value = newValue;
},
);
},
);
}
}
I hope you got value out of this, if you did, you can subscribe to the newsletter that I will put out with updates and best practices.😉 For more, content like this, visit Flutter World.