Unverified Commit c746be66 authored by nt4f04uNd's avatar nt4f04uNd Committed by GitHub

Fix precision error in RenderSliverFixedExtentBoxAdaptor assertion (#95598)

parent 5c853229
......@@ -68,7 +68,7 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
if (itemExtent > 0.0) {
final double actual = scrollOffset / itemExtent;
final int round = actual.round();
if ((actual - round).abs() < precisionErrorTolerance) {
if ((actual * itemExtent - round * itemExtent).abs() < precisionErrorTolerance) {
return round;
}
return actual.floor();
......@@ -88,7 +88,7 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
if (itemExtent > 0.0) {
final double actual = scrollOffset / itemExtent - 1;
final int round = actual.round();
if (_isWithinPrecisionErrorTolerance(actual, round)) {
if ((actual * itemExtent - round * itemExtent).abs() < precisionErrorTolerance) {
return math.max(0, round);
}
return math.max(0, actual.ceil());
......@@ -358,7 +358,3 @@ class RenderSliverFixedExtentList extends RenderSliverFixedExtentBoxAdaptor {
markNeedsLayout();
}
}
bool _isWithinPrecisionErrorTolerance(double actual, int round) {
return (actual - round).abs() < precisionErrorTolerance;
}
......@@ -45,8 +45,8 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/68182
const double genericItemExtent = 600.0;
const double extraValueToNotHaveRoundingIssues = 0.0000001; // 6 zeros
const double extraValueToHaveRoundingIssues = 0.00000001; // 7 zeros
const double extraValueToNotHaveRoundingIssues = 1e-10;
const double extraValueToHaveRoundingIssues = 1e-11;
test('should be 0 when item extent is 0', () {
const double offsetValueWhichDoesntCare = 1234;
......@@ -91,7 +91,7 @@ void main() {
expect(actual, 5);
});
test('should be 5 when offset is 6 times greater than a specific item extent where the division will return more than 13 zero decimals', () {
test('should be 5 when offset is 6 times greater than a specific item extent where the division will return more than 13 zero decimals', () {
const double itemExtentSpecificForAProblematicScreenSize = 411.42857142857144;
final int actual = testGetMaxChildIndexForScrollOffset(
itemExtentSpecificForAProblematicScreenSize * 6 + extraValueToHaveRoundingIssues,
......@@ -100,7 +100,7 @@ void main() {
expect(actual, 5);
});
test('should be 0 when offset is 0.00000001 times greater than item extent where the division will return more than 13 zero decimals', () {
test('should be 0 when offset is a bit greater than item extent', () {
final int actual = testGetMaxChildIndexForScrollOffset(
genericItemExtent + extraValueToHaveRoundingIssues,
genericItemExtent,
......
......@@ -1096,4 +1096,31 @@ void main() {
expect(tester.widget<SliverFillViewport>(viewportFinder()).padEnds, false);
});
testWidgets('PageView - precision error inside RenderSliverFixedExtentBoxAdaptor', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/95101
final PageController controller = PageController(initialPage: 152);
await tester.pumpWidget(
Center(
child: SizedBox(
width: 392.72727272727275,
child: Directionality(
textDirection: TextDirection.ltr,
child: PageView.builder(
controller: controller,
itemCount: 366,
itemBuilder: (BuildContext context, int index) {
return const SizedBox();
},
),
),
),
),
);
controller.jumpToPage(365);
await tester.pump();
expect(tester.takeException(), isNull);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment