From 6f2ca4025b54e9d41652ab549dc28a2eacce02dd Mon Sep 17 00:00:00 2001 From: xubaolin Date: Wed, 9 Jun 2021 10:39:03 +0800 Subject: [PATCH] fix a ListWheelScrollView childDelegate update bug (#82675) --- .../src/widgets/list_wheel_scroll_view.dart | 4 ++- .../flutter/test/cupertino/picker_test.dart | 30 ++++++++++++++--- .../widgets/list_wheel_scroll_view_test.dart | 33 ++++++++++++++++++- 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart b/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart index b16699aae98..31eead2164e 100644 --- a/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart +++ b/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart @@ -843,8 +843,10 @@ class ListWheelElement extends RenderObjectElement implements ListWheelChildMana final ListWheelChildDelegate newDelegate = newWidget.childDelegate; final ListWheelChildDelegate oldDelegate = oldWidget.childDelegate; if (newDelegate != oldDelegate && - (newDelegate.runtimeType != oldDelegate.runtimeType || newDelegate.shouldRebuild(oldDelegate))) + (newDelegate.runtimeType != oldDelegate.runtimeType || newDelegate.shouldRebuild(oldDelegate))) { performRebuild(); + renderObject.markNeedsLayout(); + } } @override diff --git a/packages/flutter/test/cupertino/picker_test.dart b/packages/flutter/test/cupertino/picker_test.dart index f56df59316e..e94f7113536 100644 --- a/packages/flutter/test/cupertino/picker_test.dart +++ b/packages/flutter/test/cupertino/picker_test.dart @@ -48,9 +48,32 @@ void main() { }); group('layout', () { + // Regression test for https://github.com/flutter/flutter/issues/22999 + testWidgets('CupertinoPicker.builder test', (WidgetTester tester) async { + Widget buildFrame(int childCount) { + return Directionality( + textDirection: TextDirection.ltr, + child: CupertinoPicker.builder( + itemExtent: 50.0, + onSelectedItemChanged: (_) { }, + itemBuilder: (BuildContext context, int index) { + return Text('$index'); + }, + childCount: childCount, + ), + ); + } + + await tester.pumpWidget(buildFrame(1)); + expect(tester.renderObject(find.text('0')).attached, true); + + await tester.pumpWidget(buildFrame(2)); + expect(tester.renderObject(find.text('0')).attached, true); + expect(tester.renderObject(find.text('1')).attached, true); + }); + testWidgets('selected item is in the middle', (WidgetTester tester) async { - final FixedExtentScrollController controller = - FixedExtentScrollController(initialItem: 1); + final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 1); await tester.pumpWidget( Directionality( @@ -285,8 +308,7 @@ void main() { ); testWidgets('a drag in between items settles back', (WidgetTester tester) async { - final FixedExtentScrollController controller = - FixedExtentScrollController(initialItem: 10); + final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 10); final List selectedItems = []; await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart b/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart index 1508ea99925..3a4492baa46 100644 --- a/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart +++ b/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart @@ -77,7 +77,6 @@ void main() { expect(tester.getSize(find.byType(ListWheelScrollView)), const Size(800.0, 600.0)); }); - testWidgets('ListWheelScrollView needs positive magnification', (WidgetTester tester) async { expect( () { @@ -283,6 +282,38 @@ void main() { }); group('layout', () { + // Regression test for https://github.com/flutter/flutter/issues/58144 + testWidgets('ListWheelScrollView childDelegate update test', (WidgetTester tester) async { + final FixedExtentScrollController controller = FixedExtentScrollController(); + Widget buildFrame(int childCount) { + return Directionality( + textDirection: TextDirection.ltr, + child: ListWheelScrollView.useDelegate( + controller: controller, + itemExtent: 100.0, + onSelectedItemChanged: (_) { }, + childDelegate: ListWheelChildBuilderDelegate( + childCount: childCount, + builder: (BuildContext context, int index) { + return SizedBox( + width: 400.0, + height: 100.0, + child: Text(index.toString()), + ); + }, + ), + ), + ); + } + + await tester.pumpWidget(buildFrame(1)); + expect(tester.renderObject(find.text('0')).attached, true); + + await tester.pumpWidget(buildFrame(2)); + expect(tester.renderObject(find.text('0')).attached, true); + expect(tester.renderObject(find.text('1')).attached, true); + }); + testWidgets("ListWheelScrollView takes parent's size with small children", (WidgetTester tester) async { await tester.pumpWidget( Directionality(