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

Fix/ValueListenableBuilder rebuilds (#72707)

parent 7711c1ef
......@@ -179,7 +179,9 @@ class _ValueListenableBuilderState<T> extends State<ValueListenableBuilder<T>> {
}
void _valueChanged() {
setState(() { value = widget.valueListenable.value; });
if (value != widget.valueListenable.value) {
setState(() { value = widget.valueListenable.value; });
}
}
@override
......
......@@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart';
void main() {
late SpyStringValueNotifier valueListenable;
late Widget textBuilderUnderTest;
late int rebuildCount;
Widget builderForValueListenable(
ValueListenable<String?> valueListenable,
......@@ -18,6 +19,8 @@ void main() {
child: ValueListenableBuilder<String?>(
valueListenable: valueListenable,
builder: (BuildContext context, String? value, Widget? child) {
rebuildCount += 1;
if (value == null)
return const Placeholder();
return Text(value);
......@@ -29,6 +32,7 @@ void main() {
setUp(() {
valueListenable = SpyStringValueNotifier(null);
textBuilderUnderTest = builderForValueListenable(valueListenable);
rebuildCount = 0;
});
testWidgets('Null value is ok', (WidgetTester tester) async {
......@@ -58,6 +62,46 @@ void main() {
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 {
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