Commit 8f92cb71 authored by Kate Lovett's avatar Kate Lovett Committed by Flutter GitHub Bot

Fixing PageScrollPhysics to get along with NestedScrollView (#48457)

parent 6495d377
......@@ -471,19 +471,19 @@ class PageScrollPhysics extends ScrollPhysics {
return PageScrollPhysics(parent: buildParent(ancestor));
}
double _getPage(ScrollPosition position) {
double _getPage(ScrollMetrics position) {
if (position is _PagePosition)
return position.page;
return position.pixels / position.viewportDimension;
}
double _getPixels(ScrollPosition position, double page) {
double _getPixels(ScrollMetrics position, double page) {
if (position is _PagePosition)
return position.getPixelsFromPage(page);
return page * position.viewportDimension;
}
double _getTargetPixels(ScrollPosition position, Tolerance tolerance, double velocity) {
double _getTargetPixels(ScrollMetrics position, Tolerance tolerance, double velocity) {
double page = _getPage(position);
if (velocity < -tolerance.velocity)
page -= 0.5;
......@@ -500,7 +500,7 @@ class PageScrollPhysics extends ScrollPhysics {
(velocity >= 0.0 && position.pixels >= position.maxScrollExtent))
return super.createBallisticSimulation(position, velocity);
final Tolerance tolerance = this.tolerance;
final double target = _getTargetPixels(position as ScrollPosition, tolerance, velocity);
final double target = _getTargetPixels(position, tolerance, velocity);
if (target != position.pixels)
return ScrollSpringSimulation(spring, position.pixels, target, velocity, tolerance: tolerance);
return null;
......
......@@ -4,16 +4,23 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
class TestScrollPhysics extends ScrollPhysics {
const TestScrollPhysics({ this.name, ScrollPhysics parent }) : super(parent: parent);
const TestScrollPhysics({
this.name,
ScrollPhysics parent
}) : super(parent: parent);
final String name;
@override
TestScrollPhysics applyTo(ScrollPhysics ancestor) {
return TestScrollPhysics(name: name, parent: parent?.applyTo(ancestor) ?? ancestor);
return TestScrollPhysics(
name: name,
parent: parent?.applyTo(ancestor) ?? ancestor,
);
}
TestScrollPhysics get namedParent => parent as TestScrollPhysics;
......@@ -62,20 +69,30 @@ void main() {
String types(ScrollPhysics s) => s.parent == null ? '${s.runtimeType}' : '${s.runtimeType} ${types(s.parent)}';
expect(types(bounce.applyTo(clamp.applyTo(never.applyTo(always.applyTo(page))))),
'BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics');
expect(
types(bounce.applyTo(clamp.applyTo(never.applyTo(always.applyTo(page))))),
'BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics',
);
expect(types(clamp.applyTo(never.applyTo(always.applyTo(page.applyTo(bounce))))),
'ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics');
expect(
types(clamp.applyTo(never.applyTo(always.applyTo(page.applyTo(bounce))))),
'ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics',
);
expect(types(never.applyTo(always.applyTo(page.applyTo(bounce.applyTo(clamp))))),
'NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics');
expect(
types(never.applyTo(always.applyTo(page.applyTo(bounce.applyTo(clamp))))),
'NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics',
);
expect(types(always.applyTo(page.applyTo(bounce.applyTo(clamp.applyTo(never))))),
'AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics');
expect(
types(always.applyTo(page.applyTo(bounce.applyTo(clamp.applyTo(never))))),
'AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics',
);
expect(types(page.applyTo(bounce.applyTo(clamp.applyTo(never.applyTo(always))))),
'PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics');
expect(
types(page.applyTo(bounce.applyTo(clamp.applyTo(never.applyTo(always))))),
'PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics',
);
});
group('BouncingScrollPhysics test', () {
......@@ -115,7 +132,10 @@ void main() {
expect(moreOverscrollApplied, lessThan(20.0));
// Scrolling from a more overscrolled position meets more resistance.
expect(lessOverscrollApplied.abs(), greaterThan(moreOverscrollApplied.abs()));
expect(
lessOverscrollApplied.abs(),
greaterThan(moreOverscrollApplied.abs()),
);
});
test('easing an overscroll still has resistance', () {
......@@ -143,8 +163,14 @@ void main() {
axisDirection: AxisDirection.down,
);
expect(physicsUnderTest.applyPhysicsToUserOffset(scrollPosition, 10.0), 10.0);
expect(physicsUnderTest.applyPhysicsToUserOffset(scrollPosition, -10.0), -10.0);
expect(
physicsUnderTest.applyPhysicsToUserOffset(scrollPosition, 10.0),
10.0,
);
expect(
physicsUnderTest.applyPhysicsToUserOffset(scrollPosition, -10.0),
-10.0,
);
});
test('easing an overscroll meets less resistance than tensioning', () {
......@@ -222,7 +248,9 @@ void main() {
// RegExp matcher is required here due to flutter web and flutter mobile generating
// slightly different floating point numbers
// in Flutter web 0.0 sometimes just appears as 0. or 0
expect(error.toStringDeep(), matches(RegExp(
expect(
error.toStringDeep(),
matches(RegExp(
r'''FlutterError
ClampingScrollPhysics\.applyBoundaryConditions\(\) was called
redundantly\.
......@@ -236,8 +264,33 @@ void main() {
The position object in question was\:
FixedScrollMetrics\(500(\.\d*)?..\[0(\.\d*)?\]..500(\.\d*)?\)
''',
multiLine: true,
)));
multiLine: true,
))
);
}
});
testWidgets('PageScrollPhysics work with NestedScrollView', (WidgetTester tester) async {
// Regression test for: https://github.com/flutter/flutter/issues/47850
await tester.pumpWidget(Material(
child: Directionality(
textDirection: TextDirection.ltr,
child: NestedScrollView(
physics: const PageScrollPhysics(),
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverToBoxAdapter(child: Container(height: 300, color: Colors.blue)),
];
},
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Text('Index $index');
},
itemCount: 100,
),
),
)
));
await tester.fling(find.text('Index 2'), const Offset(0.0, -300.0), 10000.0);
});
}
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