Unverified Commit 4bc35fc8 authored by Dan Field's avatar Dan Field Committed by GitHub

Allow DSS to be dragged when its children do not fill extent (#31832)

* Allow DSS to be dragged when its children do not fill extent

* Fix when maxChildSize  < 1.0
parent c0d5fd23
......@@ -262,13 +262,16 @@ class _DraggableSheetExtent {
}
double get currentExtent => _currentExtent.value;
double get additionalMinExtent => isAtMin ? 0.0 : 1.0;
double get additionalMaxExtent => isAtMax ? 0.0 : 1.0;
/// The scroll position gets inputs in terms of pixels, but the extent is
/// expected to be expressed as a number between 0..1.
void addPixelDelta(double delta, BuildContext context) {
if (availablePixels == 0) {
return;
}
currentExtent += delta / availablePixels;
currentExtent += delta / availablePixels * maxExtent;
DraggableScrollableNotification(
minExtent: minExtent,
maxExtent: maxExtent,
......@@ -426,6 +429,17 @@ class _DraggableScrollableSheetScrollPosition
final _DraggableSheetExtent extent;
bool get listShouldScroll => pixels > 0.0;
@override
bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
// We need to provide some extra extent if we haven't yet reached the max or
// min extents. Otherwise, a list with fewer children than the extent of
// the available space will get stuck.
return super.applyContentDimensions(
minScrollExtent - extent.additionalMinExtent,
maxScrollExtent + extent.additionalMaxExtent,
);
}
@override
void applyUserOffset(double delta) {
if (!listShouldScroll &&
......
......@@ -297,6 +297,7 @@ void main() {
children: <TestSemantics>[
TestSemantics(
flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
actions: <SemanticsAction>[SemanticsAction.scrollDown, SemanticsAction.scrollUp],
children: <TestSemantics>[
TestSemantics(
label: 'BottomSheet',
......
......@@ -8,7 +8,14 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
Widget _boilerplate(VoidCallback onButtonPressed) {
Widget _boilerplate(VoidCallback onButtonPressed, {
int itemCount = 100,
double initialChildSize = .5,
double maxChildSize = 1.0,
double minChildSize = .25,
double itemExtent,
Key containerKey,
}) {
return Directionality(
textDirection: TextDirection.ltr,
child: Stack(
......@@ -18,14 +25,17 @@ void main() {
onPressed: onButtonPressed,
),
DraggableScrollableSheet(
maxChildSize: 1.0,
minChildSize: .25,
maxChildSize: maxChildSize,
minChildSize: minChildSize,
initialChildSize: initialChildSize,
builder: (BuildContext context, ScrollController scrollController) {
return Container(
key: containerKey,
color: const Color(0xFFABCDEF),
child: ListView.builder(
controller: scrollController,
itemCount: 100,
itemExtent: itemExtent,
itemCount: itemCount,
itemBuilder: (BuildContext context, int index) => Text('Item $index'),
),
);
......@@ -36,6 +46,38 @@ void main() {
);
}
testWidgets('Scrolls correct amount when maxChildSize < 1.0', (WidgetTester tester) async {
const Key key = ValueKey<String>('container');
await tester.pumpWidget(_boilerplate(
null,
maxChildSize: .6,
initialChildSize: .25,
itemExtent: 25.0,
containerKey: key,
));
expect(tester.getRect(find.byKey(key)), const Rect.fromLTRB(0.0, 450.0, 800.0, 600.0));
await tester.drag(find.text('Item 5'), const Offset(0, -125));
await tester.pumpAndSettle();
expect(tester.getRect(find.byKey(key)), const Rect.fromLTRB(0.0, 325.0, 800.0, 600.0));
});
testWidgets('Scrolls correct amount when maxChildSize == 1.0', (WidgetTester tester) async {
const Key key = ValueKey<String>('container');
await tester.pumpWidget(_boilerplate(
null,
maxChildSize: 1.0,
initialChildSize: .25,
itemExtent: 25.0,
containerKey: key,
));
expect(tester.getRect(find.byKey(key)), const Rect.fromLTRB(0.0, 450.0, 800.0, 600.0));
await tester.drag(find.text('Item 5'), const Offset(0, -125));
await tester.pumpAndSettle();
expect(tester.getRect(find.byKey(key)), const Rect.fromLTRB(0.0, 325.0, 800.0, 600.0));
});
for (TargetPlatform platform in TargetPlatform.values) {
group('$platform Scroll Physics', () {
debugDefaultTargetPlatformOverride = platform;
......@@ -74,6 +116,23 @@ void main() {
expect(find.text('Item 36'), findsNothing);
});
testWidgets('Can be dragged down when list is shorter than full height', (WidgetTester tester) async {
await tester.pumpWidget(_boilerplate(null, itemCount: 30, initialChildSize: .25));
expect(find.text('Item 1').hitTestable(), findsOneWidget);
expect(find.text('Item 29').hitTestable(), findsNothing);
await tester.drag(find.text('Item 1'), const Offset(0, -325));
await tester.pumpAndSettle();
expect(find.text('Item 1').hitTestable(), findsOneWidget);
expect(find.text('Item 29').hitTestable(), findsOneWidget);
await tester.drag(find.text('Item 1'), const Offset(0, 325));
await tester.pumpAndSettle();
expect(find.text('Item 1').hitTestable(), findsOneWidget);
expect(find.text('Item 29').hitTestable(), findsNothing);
});
testWidgets('Can be dragged up and cover its container and scroll in single motion, and then dragged back down', (WidgetTester tester) async {
int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
......
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