Update DraggableScrollableSheet docs to reflect API change (#136471)
### Description This PR intends to update `DraggableScrollableSheet` docs for Web and Desktop platforms. On these platforms, the vertical dragging gesture does not provide natural behavior similar to other desktop applications. By adding a note before the sample code so users are aware that the sample code will not work as expected on Desktop and Web. Also, refer to the instructions if they still want to implement it on these platforms. ### Related issue Fixes https://github.com/flutter/flutter/issues/111372
This commit is contained in:
parent
1b9cab7138
commit
61c007a3f7
@ -0,0 +1,144 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Flutter code sample for [DraggableScrollableSheet].
|
||||
|
||||
void main() => runApp(const DraggableScrollableSheetExampleApp());
|
||||
|
||||
class DraggableScrollableSheetExampleApp extends StatelessWidget {
|
||||
const DraggableScrollableSheetExampleApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue.shade100),
|
||||
),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('DraggableScrollableSheet Sample'),
|
||||
),
|
||||
body: const DraggableScrollableSheetExample(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DraggableScrollableSheetExample extends StatefulWidget {
|
||||
const DraggableScrollableSheetExample({super.key});
|
||||
|
||||
@override
|
||||
State<DraggableScrollableSheetExample> createState() => _DraggableScrollableSheetExampleState();
|
||||
}
|
||||
|
||||
class _DraggableScrollableSheetExampleState extends State<DraggableScrollableSheetExample> {
|
||||
double _sheetPosition = 0.5;
|
||||
final double _dragSensitivity = 600;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return DraggableScrollableSheet(
|
||||
initialChildSize: _sheetPosition,
|
||||
builder: (BuildContext context, ScrollController scrollController) {
|
||||
return ColoredBox(
|
||||
color: colorScheme.primary,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Grabber(
|
||||
onVerticalDragUpdate: (DragUpdateDetails details) {
|
||||
setState(() {
|
||||
_sheetPosition -= details.delta.dy / _dragSensitivity;
|
||||
if (_sheetPosition < 0.25) {
|
||||
_sheetPosition = 0.25;
|
||||
}
|
||||
if (_sheetPosition > 1.0) {
|
||||
_sheetPosition = 1.0;
|
||||
}
|
||||
});
|
||||
},
|
||||
isOnDesktopAndWeb: _isOnDesktopAndWeb,
|
||||
),
|
||||
Flexible(
|
||||
child: ListView.builder(
|
||||
controller: _isOnDesktopAndWeb ? null : scrollController,
|
||||
itemCount: 25,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ListTile(
|
||||
title: Text(
|
||||
'Item $index',
|
||||
style: TextStyle(color: colorScheme.surface),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
bool get _isOnDesktopAndWeb {
|
||||
if (kIsWeb) {
|
||||
return true;
|
||||
}
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.macOS:
|
||||
case TargetPlatform.linux:
|
||||
case TargetPlatform.windows:
|
||||
return true;
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.fuchsia:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A draggable widget that accepts vertical drag gestures
|
||||
/// and this is only visible on desktop and web platforms.
|
||||
class Grabber extends StatelessWidget {
|
||||
const Grabber({
|
||||
super.key,
|
||||
required this.onVerticalDragUpdate,
|
||||
required this.isOnDesktopAndWeb,
|
||||
});
|
||||
|
||||
final ValueChanged<DragUpdateDetails> onVerticalDragUpdate;
|
||||
final bool isOnDesktopAndWeb;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!isOnDesktopAndWeb) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return GestureDetector(
|
||||
onVerticalDragUpdate: onVerticalDragUpdate,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
color: colorScheme.onSurface,
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
width: 32.0,
|
||||
height: 4.0,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceVariant,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_api_samples/widgets/draggable_scrollable_sheet/draggable_scrollable_sheet.0.dart' as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Test DraggableScrollableSheet initial state', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.DraggableScrollableSheetExampleApp(),
|
||||
);
|
||||
|
||||
final Finder sheetFinder = find.byType(DraggableScrollableSheet);
|
||||
|
||||
// Verify that DraggableScrollableSheet is initially present
|
||||
expect(sheetFinder, findsOneWidget);
|
||||
|
||||
// Verify that DraggableScrollableSheet is shown initially at 50% height
|
||||
final DraggableScrollableSheet draggableSheet = tester.widget(sheetFinder);
|
||||
expect(draggableSheet.initialChildSize, 0.5);
|
||||
});
|
||||
|
||||
testWidgets('Test DraggableScrollableSheet drag behavior on mobile platforms', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.DraggableScrollableSheetExampleApp(),
|
||||
);
|
||||
|
||||
// Verify that ListView is visible
|
||||
final Finder listViewFinder = find.byType(ListView);
|
||||
expect(listViewFinder, findsOneWidget);
|
||||
|
||||
// Get the initial size of the ListView
|
||||
final Size listViewInitialSize = tester.getSize(listViewFinder);
|
||||
|
||||
// Drag the the sheet from anywhere inside the sheet to change the sheet position
|
||||
await tester.drag(listViewFinder, const Offset(0.0, -100.0));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that the ListView is expanded
|
||||
final Size listViewCurrentSize = tester.getSize(listViewFinder);
|
||||
expect(listViewCurrentSize.height, greaterThan(listViewInitialSize.height));
|
||||
}, variant: TargetPlatformVariant.mobile());
|
||||
|
||||
testWidgets('Test DraggableScrollableSheet drag behavior on desktop platforms', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.DraggableScrollableSheetExampleApp(),
|
||||
);
|
||||
|
||||
// Verify that Grabber is visible
|
||||
final Finder grabberFinder = find.byType(example.Grabber);
|
||||
expect(grabberFinder, findsOneWidget);
|
||||
|
||||
// Drag the Grabber to change the sheet position
|
||||
await tester.drag(grabberFinder, const Offset(0.0, -100.0));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that the DraggableScrollableSheet's initialChildSize is updated
|
||||
final DraggableScrollableSheet draggableSheet = tester.widget(find.byType(DraggableScrollableSheet));
|
||||
expect(draggableSheet.initialChildSize, isNot(0.5));
|
||||
}, variant: TargetPlatformVariant.desktop());
|
||||
}
|
@ -260,7 +260,7 @@ class DraggableScrollableController extends ChangeNotifier {
|
||||
/// to position sheet based on the space it is taking, the [expand] property
|
||||
/// may be set to false.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// {@tool dartpad}
|
||||
///
|
||||
/// This is a sample widget which shows a [ListView] that has 25 [ListTile]s.
|
||||
/// It starts out as taking up half the body of the [Scaffold], and can be
|
||||
@ -269,36 +269,16 @@ class DraggableScrollableController extends ChangeNotifier {
|
||||
/// scrolled up or down, until they reach the top of the list again and the user
|
||||
/// drags the sheet back down.
|
||||
///
|
||||
/// ```dart
|
||||
/// class HomePage extends StatelessWidget {
|
||||
/// const HomePage({super.key});
|
||||
/// On desktop and web running on desktop platforms, dragging to scroll with a mouse is disabled by default
|
||||
/// to align with the natural behavior found in other desktop applications.
|
||||
///
|
||||
/// @override
|
||||
/// Widget build(BuildContext context) {
|
||||
/// return Scaffold(
|
||||
/// appBar: AppBar(
|
||||
/// title: const Text('DraggableScrollableSheet'),
|
||||
/// ),
|
||||
/// body: SizedBox.expand(
|
||||
/// child: DraggableScrollableSheet(
|
||||
/// builder: (BuildContext context, ScrollController scrollController) {
|
||||
/// return Container(
|
||||
/// color: Colors.blue[100],
|
||||
/// child: ListView.builder(
|
||||
/// controller: scrollController,
|
||||
/// itemCount: 25,
|
||||
/// itemBuilder: (BuildContext context, int index) {
|
||||
/// return ListTile(title: Text('Item $index'));
|
||||
/// },
|
||||
/// ),
|
||||
/// );
|
||||
/// },
|
||||
/// ),
|
||||
/// ),
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// This behavior is dictated by the [ScrollBehavior], and can be changed by adding
|
||||
/// [PointerDeviceKind.mouse] to [ScrollBehavior.dragDevices].
|
||||
/// For more info on this, please refer to https://docs.flutter.dev/release/breaking-changes/default-scroll-behavior-drag
|
||||
///
|
||||
/// Alternatively, this example illustrates how to add a drag handle for desktop applications.
|
||||
///
|
||||
/// ** See code in examples/api/lib/widgets/draggable_scrollable_sheet/draggable_scrollable_sheet.0.dart **
|
||||
/// {@end-tool}
|
||||
class DraggableScrollableSheet extends StatefulWidget {
|
||||
/// Creates a widget that can be dragged and scrolled in a single gesture.
|
||||
|
Loading…
x
Reference in New Issue
Block a user