Skip to content

Commit

Permalink
Guard against zero item extent for carousel (flutter#163310)
Browse files Browse the repository at this point in the history
This PR fixes a bug where the `CarouselView` would throw an error if the
itemExtent is zero.

Part of flutter#160679

*If you had to change anything in the [flutter/tests] repo, include a
link to the migration guide as per the [breaking change policy].*

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
  • Loading branch information
navaronbracke authored Feb 26, 2025
1 parent 0b96fa8 commit d8100ac
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
12 changes: 12 additions & 0 deletions packages/flutter/lib/src/material/carousel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,10 @@ class _RenderSliverFixedExtentCarousel extends RenderSliverFixedExtentBoxAdaptor

// This implements the [itemExtentBuilder] callback.
double _buildItemExtent(int index, SliverLayoutDimensions currentLayoutDimensions) {
if (maxExtent == 0.0) {
return maxExtent;
}

final int firstVisibleIndex = (constraints.scrollOffset / maxExtent).floor();

// Calculate how many items have been completely scroll off screen.
Expand Down Expand Up @@ -641,6 +645,10 @@ class _RenderSliverFixedExtentCarousel extends RenderSliverFixedExtentBoxAdaptor
double itemExtent,
int index,
) {
if (maxExtent == 0.0) {
return maxExtent;
}

final int firstVisibleIndex = (constraints.scrollOffset / maxExtent).floor();

// If there is not enough space to place the last visible item but the remaining
Expand Down Expand Up @@ -673,6 +681,10 @@ class _RenderSliverFixedExtentCarousel extends RenderSliverFixedExtentBoxAdaptor
)
double itemExtent,
) {
if (maxExtent == 0.0) {
return 0;
}

final int firstVisibleIndex = (constraints.scrollOffset / maxExtent).floor();
return math.max(firstVisibleIndex, 0);
}
Expand Down
19 changes: 19 additions & 0 deletions packages/flutter/test/material/carousel_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,25 @@ void main() {
expect(buttonPressed, isTrue);
},
);

// Regression test for https://github.com/flutter/flutter/issues/160679
testWidgets('CarouselView does not crash if itemExtent is zero', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: SizedBox(
width: 100,
child: CarouselView(
itemExtent: 0,
children: <Widget>[Container(color: Colors.red, width: 100, height: 100)],
),
),
),
),
);

expect(tester.takeException(), isNull);
});
}

Finder getItem(int index) {
Expand Down

0 comments on commit d8100ac

Please sign in to comment.