Unverified Commit 328635b3 authored by xubaolin's avatar xubaolin Committed by GitHub

DraggableScrollableSheet & NestedScrollView should respect NeverScrollableScrollPhysics (#123109)

DraggableScrollableSheet & NestedScrollView  should respect NeverScrollableScrollPhysics
parent c0c5901c
...@@ -781,7 +781,7 @@ class _DraggableScrollableSheetScrollController extends ScrollController { ...@@ -781,7 +781,7 @@ class _DraggableScrollableSheetScrollController extends ScrollController {
ScrollPosition? oldPosition, ScrollPosition? oldPosition,
) { ) {
return _DraggableScrollableSheetScrollPosition( return _DraggableScrollableSheetScrollPosition(
physics: const AlwaysScrollableScrollPhysics().applyTo(physics), physics: physics.applyTo(const AlwaysScrollableScrollPhysics()),
context: context, context: context,
oldPosition: oldPosition, oldPosition: oldPosition,
getExtent: () => extent, getExtent: () => extent,
......
...@@ -1439,7 +1439,8 @@ class _NestedScrollPosition extends ScrollPosition implements ScrollActivityDele ...@@ -1439,7 +1439,8 @@ class _NestedScrollPosition extends ScrollPosition implements ScrollActivityDele
} }
void updateCanDrag(double totalExtent) { void updateCanDrag(double totalExtent) {
context.setCanDrag(totalExtent > (viewportDimension - maxScrollExtent) || minScrollExtent != maxScrollExtent); context.setCanDrag(physics.allowUserScrolling &&
(totalExtent > (viewportDimension - maxScrollExtent) || minScrollExtent != maxScrollExtent));
} }
@override @override
......
...@@ -197,7 +197,8 @@ class ScrollPhysics { ...@@ -197,7 +197,8 @@ class ScrollPhysics {
} }
/// Whether the scrollable should let the user adjust the scroll offset, for /// Whether the scrollable should let the user adjust the scroll offset, for
/// example by dragging. /// example by dragging. If [allowUserScrolling] is false, the scrollable
/// will never allow user input to change the scroll position.
/// ///
/// By default, the user can manipulate the scroll offset if, and only if, /// By default, the user can manipulate the scroll offset if, and only if,
/// there is actually content outside the viewport to reveal. /// there is actually content outside the viewport to reveal.
...@@ -206,6 +207,10 @@ class ScrollPhysics { ...@@ -206,6 +207,10 @@ class ScrollPhysics {
/// reference to it to use later, as the values may update, may not update, or /// reference to it to use later, as the values may update, may not update, or
/// may update to reflect an entirely unrelated scrollable. /// may update to reflect an entirely unrelated scrollable.
bool shouldAcceptUserOffset(ScrollMetrics position) { bool shouldAcceptUserOffset(ScrollMetrics position) {
if (!allowUserScrolling) {
return false;
}
if (parent == null) { if (parent == null) {
return position.pixels != 0.0 || position.minScrollExtent != position.maxScrollExtent; return position.pixels != 0.0 || position.minScrollExtent != position.maxScrollExtent;
} }
...@@ -487,6 +492,9 @@ class ScrollPhysics { ...@@ -487,6 +492,9 @@ class ScrollPhysics {
/// scroll position to fulfill such a request. /// scroll position to fulfill such a request.
bool get allowImplicitScrolling => true; bool get allowImplicitScrolling => true;
/// Whether a viewport is allowed to change the scroll position as the result of user input.
bool get allowUserScrolling => true;
@override @override
String toString() { String toString() {
if (parent == null) { if (parent == null) {
...@@ -965,7 +973,7 @@ class NeverScrollableScrollPhysics extends ScrollPhysics { ...@@ -965,7 +973,7 @@ class NeverScrollableScrollPhysics extends ScrollPhysics {
} }
@override @override
bool shouldAcceptUserOffset(ScrollMetrics position) => false; bool get allowUserScrolling => false;
@override @override
bool get allowImplicitScrolling => false; bool get allowImplicitScrolling => false;
......
...@@ -1487,6 +1487,51 @@ void main() { ...@@ -1487,6 +1487,51 @@ void main() {
); );
}); });
testWidgets('DraggableScrollableSheet should respect NeverScrollableScrollPhysics', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/121021
final DraggableScrollableController controller = DraggableScrollableController();
Widget buildFrame(ScrollPhysics? physics) {
return MaterialApp(
home: Scaffold(
body: DraggableScrollableSheet(
controller: controller,
initialChildSize: 0.25,
builder: (BuildContext context, ScrollController scrollController) {
return ListView(
physics: physics,
controller: scrollController,
children: <Widget>[
const Text('Drag me!'),
Container(
height: 10000.0,
color: Colors.blue,
),
],
);
},
),
),
);
}
await tester.pumpWidget(buildFrame(const NeverScrollableScrollPhysics()));
final double initPixels = controller.pixels;
await tester.drag(find.text('Drag me!'), const Offset(0, -300));
await tester.pumpAndSettle();
//Should not allow user scrolling.
expect(controller.pixels, initPixels);
await tester.pumpWidget(buildFrame(null));
await tester.drag(find.text('Drag me!'), const Offset(0, -300.0));
await tester.pumpAndSettle();
//Allow user scrolling.
expect(controller.pixels, initPixels + 300.0);
});
testWidgets('DraggableScrollableSheet should not rebuild every frame while dragging', (WidgetTester tester) async { testWidgets('DraggableScrollableSheet should not rebuild every frame while dragging', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/67219 // Regression test for https://github.com/flutter/flutter/issues/67219
int buildCount = 0; int buildCount = 0;
......
...@@ -531,6 +531,47 @@ void main() { ...@@ -531,6 +531,47 @@ void main() {
expect(point1.dy, greaterThan(point2.dy)); expect(point1.dy, greaterThan(point2.dy));
}); });
testWidgets('NestedScrollViews respect NeverScrollableScrollPhysics', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/113753
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: Localizations(
locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
child: MediaQuery(
data: const MediaQueryData(),
child: NestedScrollView(
physics: const NeverScrollableScrollPhysics(),
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
const SliverAppBar(
floating: true,
title: Text('AA'),
),
];
},
body: Container(),
),
),
),
));
expect(find.text('AA'), findsOneWidget);
final Offset point1 = tester.getCenter(find.text('AA'));
await tester.dragFrom(point1, const Offset(0.0, -200.0));
await tester.pump();
final Offset point2 = tester.getCenter(find.text(
'AA',
skipOffstage: false,
));
expect(point1, point2);
});
testWidgets('NestedScrollView and internal scrolling', (WidgetTester tester) async { testWidgets('NestedScrollView and internal scrolling', (WidgetTester tester) async {
debugDisableShadows = false; debugDisableShadows = false;
const List<String> tabs = <String>['Hello', 'World']; const List<String> tabs = <String>['Hello', 'World'];
......
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