Value Listenable Builder in Flutter, a powerful widget in Flutter that allows us to rebuild parts of our UI based on changes in a ValueNotifier. Let’s see how we can use it to create a dynamic UI that responds to user interactions without the need for setState.
Imagine you have an AnimatedContainer whose color changes when you click on it. Initially, the color is set to green. The challenge is to change the color of the container when it’s clicked, without using setState. This is where ValueListenableBuilder comes into play.
Setting Up the ValueNotifier
First, we need to create a ValueNotifier that will hold the color of our container. ValueNotifier is a simple way to listen for changes in a single value. Let’s create a ValueNotifier for our container’s color and initialize it with green.
ValueNotifier<Color> myColor = ValueNotifier<Color>(Colors.green);
Wrapping the AnimatedContainer with ValueListenableBuilder
Next, we wrap our AnimatedContainer with a ValueListenableBuilder. This widget listens to changes in the ValueNotifier and rebuilds its child widget when the value changes.
ValueListenableBuilder<Color>(
valueListenable: myColor,
builder: (context, value, child) {
return AnimatedContainer(
duration: Duration(seconds: 1),
color: value,
child: InkWell(
onTap: () {
// Change the color on tap
},
child: Container(
width: 100,
height: 100,
),
),
);
},
)
Changing the Color on Tap
Now, let’s add the logic to change the color of the container when it’s tapped. We’ll toggle between green and red colors.
InkWell(
onTap: () {
if (myColor.value == Colors.green) {
myColor.value = Colors.red;
} else {
myColor.value = Colors.green;
}
},
child: Container(
width: 100,
height: 100,
),
)
Putting It All Together
Here’s how the complete code looks:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ValueListenableBuilder<Color>(
valueListenable: myColor,
builder: (context, value, child) {
return AnimatedContainer(
duration: Duration(seconds: 1),
color: value,
child: InkWell(
onTap: () {
if (myColor.value == Colors.green) {
myColor.value = Colors.red;
} else {
myColor.value = Colors.green;
}
},
child: Container(
width: 100,
height: 100,
),
),
);
},
),
),
),
);
}
}
ValueNotifier<Color> myColor = ValueNotifier<Color>(Colors.green);
Conclusion
With ValueListenableBuilder, we can easily create dynamic UIs that respond to changes in a ValueNotifier without the need for setState. This makes our code cleaner and more maintainable, especially for complex state management scenarios.
And if you have any questions or suggestions for the future, feel free to leave a comment below. Happy coding!