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!