Unverified Commit 61c007a3 authored by huycozy's avatar huycozy Committed by GitHub

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
parent 1b9cab71
// 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),
),
),
),
),
);
}
}
// 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.
......
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