From 173bf86b7b59bb4082454b18e24f1fd51c2048ed Mon Sep 17 00:00:00 2001 From: Qun Cheng <36861262+QuncCccccc@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:04:48 -0700 Subject: [PATCH] Fix CarouselView rebuild (#152791) Fixes https://github.com/flutter/flutter/issues/152787 Originally, when we want to update `itemExtent`, we didn't check if the old itemExtent is null but `getItemFromPixels()` needs that information. https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/carousel.dart#L1343-L1347 Then in `getItemFromPixels()`, it goes to the else statement which assert `flexWeights` is not null, then the exception happens. - [x ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. --- .../flutter/lib/src/material/carousel.dart | 2 +- .../flutter/test/material/carousel_test.dart | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/carousel.dart b/packages/flutter/lib/src/material/carousel.dart index a57d819375..19c85a7e3b 100644 --- a/packages/flutter/lib/src/material/carousel.dart +++ b/packages/flutter/lib/src/material/carousel.dart @@ -1340,7 +1340,7 @@ class _CarouselPosition extends ScrollPositionWithSingleContext implements _Caro if (_itemExtent == value) { return; } - if (hasPixels) { + if (hasPixels && _itemExtent != null) { final double leadingItem = getItemFromPixels(pixels, viewportDimension); final double newPixel = getPixelsFromItem(leadingItem, flexWeights, value); forcePixels(newPixel); diff --git a/packages/flutter/test/material/carousel_test.dart b/packages/flutter/test/material/carousel_test.dart index 3754711935..062e41d02a 100644 --- a/packages/flutter/test/material/carousel_test.dart +++ b/packages/flutter/test/material/carousel_test.dart @@ -1149,6 +1149,50 @@ void main() { expect(getItem(5), findsOneWidget); expect(tester.getRect(getItem(5)).width, difference); }); + + testWidgets('Updating CarouselView does not cause exception', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/152787 + bool isLight = true; + await tester.pumpWidget( + StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return MaterialApp( + theme: Theme.of(context).copyWith( + brightness: isLight ? Brightness.light : Brightness.dark, + ), + home: Scaffold( + appBar: AppBar( + actions: [ + Switch( + value: isLight, + onChanged: (bool value) { + setState(() { + isLight = value; + }); + } + ) + ], + ), + body: CarouselView( + itemExtent: 100, + children: List.generate(10, (int index) { + return Center( + child: Text('Item $index'), + ); + }), + ), + ), + ); + } + ) + ); + await tester.pumpAndSettle(); + await tester.tap(find.byType(Switch)); + await tester.pumpAndSettle(); + + // No exception. + expect(tester.takeException(), isNull); + }); } Finder getItem(int index) {