Unverified Commit 69882d96 authored by Bogdan Lukin's avatar Bogdan Lukin Committed by GitHub

Fix/ValueListenableBuilder rebuilds (#72707)

parent 7711c1ef
...@@ -179,8 +179,10 @@ class _ValueListenableBuilderState<T> extends State<ValueListenableBuilder<T>> { ...@@ -179,8 +179,10 @@ class _ValueListenableBuilderState<T> extends State<ValueListenableBuilder<T>> {
} }
void _valueChanged() { void _valueChanged() {
if (value != widget.valueListenable.value) {
setState(() { value = widget.valueListenable.value; }); setState(() { value = widget.valueListenable.value; });
} }
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart'; ...@@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart';
void main() { void main() {
late SpyStringValueNotifier valueListenable; late SpyStringValueNotifier valueListenable;
late Widget textBuilderUnderTest; late Widget textBuilderUnderTest;
late int rebuildCount;
Widget builderForValueListenable( Widget builderForValueListenable(
ValueListenable<String?> valueListenable, ValueListenable<String?> valueListenable,
...@@ -18,6 +19,8 @@ void main() { ...@@ -18,6 +19,8 @@ void main() {
child: ValueListenableBuilder<String?>( child: ValueListenableBuilder<String?>(
valueListenable: valueListenable, valueListenable: valueListenable,
builder: (BuildContext context, String? value, Widget? child) { builder: (BuildContext context, String? value, Widget? child) {
rebuildCount += 1;
if (value == null) if (value == null)
return const Placeholder(); return const Placeholder();
return Text(value); return Text(value);
...@@ -29,6 +32,7 @@ void main() { ...@@ -29,6 +32,7 @@ void main() {
setUp(() { setUp(() {
valueListenable = SpyStringValueNotifier(null); valueListenable = SpyStringValueNotifier(null);
textBuilderUnderTest = builderForValueListenable(valueListenable); textBuilderUnderTest = builderForValueListenable(valueListenable);
rebuildCount = 0;
}); });
testWidgets('Null value is ok', (WidgetTester tester) async { testWidgets('Null value is ok', (WidgetTester tester) async {
...@@ -58,6 +62,46 @@ void main() { ...@@ -58,6 +62,46 @@ void main() {
expect(find.text('Dinesh'), findsOneWidget); expect(find.text('Dinesh'), findsOneWidget);
}); });
testWidgets('Widget does not rebuilds if value is the same', (WidgetTester tester) async {
const Duration duration = Duration(milliseconds: 100);
final AnimationController controller = AnimationController(
vsync: const TestVSync(),
duration: duration,
)..value = 0;
final Animation<String> animation = TweenSequence<String>(<TweenSequenceItem<String>>[
TweenSequenceItem<String>(tween: ConstantTween<String>('Gilfoyle'), weight: 1.0),
TweenSequenceItem<String>(tween: ConstantTween<String>('Dinesh'), weight: 1.0),
]).animate(controller);
final Finder finder1 = find.text('Gilfoyle');
final Finder finder2 = find.text('Dinesh');
await tester.pumpWidget(builderForValueListenable(animation));
await tester.pump();
expect(finder1, findsOneWidget);
expect(finder2, findsNothing);
expect(rebuildCount, equals(1));
controller.value = 0.3;
await tester.pump();
expect(finder1, findsOneWidget);
expect(finder2, findsNothing);
expect(rebuildCount, equals(1));
controller.animateTo(0.6);
await tester.pumpAndSettle(duration);
expect(finder1, findsNothing);
expect(finder2, findsOneWidget);
expect(rebuildCount, equals(2));
controller.forward();
await tester.pumpAndSettle(duration);
expect(finder1, findsNothing);
expect(finder2, findsOneWidget);
expect(rebuildCount, equals(2));
});
testWidgets('Can change listenable', (WidgetTester tester) async { testWidgets('Can change listenable', (WidgetTester tester) async {
await tester.pumpWidget(textBuilderUnderTest); await tester.pumpWidget(textBuilderUnderTest);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment