diff --git a/packages/flutter/lib/src/rendering/list_wheel_viewport.dart b/packages/flutter/lib/src/rendering/list_wheel_viewport.dart index 9a451d12ec0..bb8c80ccc2a 100644 --- a/packages/flutter/lib/src/rendering/list_wheel_viewport.dart +++ b/packages/flutter/lib/src/rendering/list_wheel_viewport.dart @@ -681,10 +681,14 @@ class RenderListWheelViewport /// by [childManager]. @override void performLayout() { - // Apply the dimensions first in case it changes the scroll offset which - // determines what should be shown. offset.applyViewportDimension(_viewportExtent); - offset.applyContentDimensions(_minEstimatedScrollExtent, _maxEstimatedScrollExtent); + // Apply the content dimensions first if it has exact dimensions in case it + // changes the scroll offset which determines what should be shown. Such as + // if the child count decrease, we should correct the pixels first, otherwise, + // it may be shown blank null children. + if (childManager.childCount != null) { + offset.applyContentDimensions(_minEstimatedScrollExtent, _maxEstimatedScrollExtent); + } // The height, in pixel, that children will be visible and might be laid out // and painted. 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 9ef92e998b7..88faa465b2c 100644 --- a/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart +++ b/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart @@ -288,6 +288,44 @@ void main() { }); group('layout', () { + testWidgets('Flings with high velocity should not break the children lower and upper limits', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/112526 + final FixedExtentScrollController controller = FixedExtentScrollController(); + Widget buildFrame() { + return Directionality( + textDirection: TextDirection.ltr, + child: ListWheelScrollView.useDelegate( + physics: const FixedExtentScrollPhysics(), + controller: controller, + itemExtent: 400.0, + onSelectedItemChanged: (_) { }, + childDelegate: ListWheelChildBuilderDelegate( + builder: (BuildContext context, int index) { + if (index < 0 || index > 5) { + return null; + } + return SizedBox( + width: 400.0, + height: 400.0, + child: Text(index.toString()), + ); + }, + ), + ), + ); + } + + await tester.pumpWidget(buildFrame()); + expect(tester.renderObject(find.text('0')).attached, true); + expect(tester.renderObject(find.text('1')).attached, true); + expect(find.text('2'), findsNothing); + expect(controller.selectedItem, 0); + + // Flings with high velocity and stop at the child boundary. + await tester.fling(find.byType(ListWheelScrollView), const Offset(0.0, 40000.0), 8000.0); + expect(controller.selectedItem, 0); + }, variant: TargetPlatformVariant(TargetPlatform.values.toSet())); + // Regression test for https://github.com/flutter/flutter/issues/90953 testWidgets('ListWheelScrollView childDelegate update test 2', (WidgetTester tester) async { final FixedExtentScrollController controller = FixedExtentScrollController( initialItem: 2 );