Unverified Commit 00d95e62 authored by chunhtai's avatar chunhtai Committed by GitHub

fix page scroll position rounding error (#34519)

parent 5c52498d
...@@ -8,6 +8,7 @@ import 'dart:math' as math; ...@@ -8,6 +8,7 @@ import 'dart:math' as math;
import 'package:flutter/physics.dart'; import 'package:flutter/physics.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/gestures.dart' show DragStartBehavior; import 'package:flutter/gestures.dart' show DragStartBehavior;
import 'package:flutter/foundation.dart' show precisionErrorTolerance;
import 'basic.dart'; import 'basic.dart';
import 'debug.dart'; import 'debug.dart';
...@@ -368,7 +369,12 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri ...@@ -368,7 +369,12 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri
} }
double getPageFromPixels(double pixels, double viewportDimension) { double getPageFromPixels(double pixels, double viewportDimension) {
return math.max(0.0, pixels) / math.max(1.0, viewportDimension * viewportFraction); final double actual = math.max(0.0, pixels) / math.max(1.0, viewportDimension * viewportFraction);
final double round = actual.roundToDouble();
if ((actual - round).abs() < precisionErrorTolerance) {
return round;
}
return actual;
} }
double getPixelsFromPage(double page) { double getPixelsFromPage(double page) {
...@@ -376,7 +382,13 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri ...@@ -376,7 +382,13 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri
} }
@override @override
double get page => pixels == null ? null : getPageFromPixels(pixels.clamp(minScrollExtent, maxScrollExtent), viewportDimension); double get page {
assert(
pixels == null || (minScrollExtent != null && maxScrollExtent != null),
'Page value is only available after content dimensions are established.',
);
return pixels == null ? null : getPageFromPixels(pixels.clamp(minScrollExtent, maxScrollExtent), viewportDimension);
}
@override @override
void saveScrollOffset() { void saveScrollOffset() {
......
...@@ -728,4 +728,24 @@ void main() { ...@@ -728,4 +728,24 @@ void main() {
); );
expect(page2.page, 4.0); expect(page2.page, 4.0);
}); });
testWidgets('Page controller can handle rounding issue', (WidgetTester tester) async {
final PageController pageController = PageController();
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: PageView(
controller: pageController,
children: List<Widget>.generate(3, (int i) {
return Semantics(
child: Text('Page #$i'),
container: true,
);
}),
),
));
// Simulate precision error.
pageController.position.jumpTo(799.99999999999);
expect(pageController.page, 1);
});
} }
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