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].
This commit is contained in:
Qun Cheng 2024-08-05 16:04:48 -07:00 committed by GitHub
parent 84eb378180
commit 173bf86b7b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 1 deletions

View File

@ -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);

View File

@ -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: <Widget>[
Switch(
value: isLight,
onChanged: (bool value) {
setState(() {
isLight = value;
});
}
)
],
),
body: CarouselView(
itemExtent: 100,
children: List<Widget>.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) {