1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | import 'package:flutter/foundation.dart'; |
6 | import 'package:flutter/material.dart'; |
7 | |
8 | /// Flutter code sample for [DraggableScrollableSheet]. |
9 | |
10 | void main() => runApp(const DraggableScrollableSheetExampleApp()); |
11 | |
12 | class DraggableScrollableSheetExampleApp extends StatelessWidget { |
13 | const DraggableScrollableSheetExampleApp({super.key}); |
14 | |
15 | @override |
16 | Widget build(BuildContext context) { |
17 | return MaterialApp( |
18 | theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue.shade100)), |
19 | home: Scaffold( |
20 | appBar: AppBar(title: const Text('DraggableScrollableSheet Sample' )), |
21 | body: const DraggableScrollableSheetExample(), |
22 | ), |
23 | ); |
24 | } |
25 | } |
26 | |
27 | class DraggableScrollableSheetExample extends StatefulWidget { |
28 | const DraggableScrollableSheetExample({super.key}); |
29 | |
30 | @override |
31 | State<DraggableScrollableSheetExample> createState() => _DraggableScrollableSheetExampleState(); |
32 | } |
33 | |
34 | class _DraggableScrollableSheetExampleState extends State<DraggableScrollableSheetExample> { |
35 | double _sheetPosition = 0.5; |
36 | final double _dragSensitivity = 600; |
37 | |
38 | @override |
39 | Widget build(BuildContext context) { |
40 | final ColorScheme colorScheme = Theme.of(context).colorScheme; |
41 | |
42 | return DraggableScrollableSheet( |
43 | initialChildSize: _sheetPosition, |
44 | builder: (BuildContext context, ScrollController scrollController) { |
45 | return ColoredBox( |
46 | color: colorScheme.primary, |
47 | child: Column( |
48 | children: <Widget>[ |
49 | Grabber( |
50 | onVerticalDragUpdate: (DragUpdateDetails details) { |
51 | setState(() { |
52 | _sheetPosition -= details.delta.dy / _dragSensitivity; |
53 | if (_sheetPosition < 0.25) { |
54 | _sheetPosition = 0.25; |
55 | } |
56 | if (_sheetPosition > 1.0) { |
57 | _sheetPosition = 1.0; |
58 | } |
59 | }); |
60 | }, |
61 | isOnDesktopAndWeb: _isOnDesktopAndWeb, |
62 | ), |
63 | Flexible( |
64 | child: ListView.builder( |
65 | controller: _isOnDesktopAndWeb ? null : scrollController, |
66 | itemCount: 25, |
67 | itemBuilder: (BuildContext context, int index) { |
68 | return ListTile( |
69 | title: Text('Item $index' , style: TextStyle(color: colorScheme.surface)), |
70 | ); |
71 | }, |
72 | ), |
73 | ), |
74 | ], |
75 | ), |
76 | ); |
77 | }, |
78 | ); |
79 | } |
80 | |
81 | bool get _isOnDesktopAndWeb => |
82 | kIsWeb || |
83 | switch (defaultTargetPlatform) { |
84 | TargetPlatform.macOS || TargetPlatform.linux || TargetPlatform.windows => true, |
85 | TargetPlatform.android || TargetPlatform.iOS || TargetPlatform.fuchsia => false, |
86 | }; |
87 | } |
88 | |
89 | /// A draggable widget that accepts vertical drag gestures |
90 | /// and this is only visible on desktop and web platforms. |
91 | class Grabber extends StatelessWidget { |
92 | const Grabber({super.key, required this.onVerticalDragUpdate, required this.isOnDesktopAndWeb}); |
93 | |
94 | final ValueChanged<DragUpdateDetails> onVerticalDragUpdate; |
95 | final bool isOnDesktopAndWeb; |
96 | |
97 | @override |
98 | Widget build(BuildContext context) { |
99 | if (!isOnDesktopAndWeb) { |
100 | return const SizedBox.shrink(); |
101 | } |
102 | final ColorScheme colorScheme = Theme.of(context).colorScheme; |
103 | |
104 | return GestureDetector( |
105 | onVerticalDragUpdate: onVerticalDragUpdate, |
106 | child: Container( |
107 | width: double.infinity, |
108 | color: colorScheme.onSurface, |
109 | child: Align( |
110 | alignment: Alignment.topCenter, |
111 | child: Container( |
112 | margin: const EdgeInsets.symmetric(vertical: 8.0), |
113 | width: 32.0, |
114 | height: 4.0, |
115 | decoration: BoxDecoration( |
116 | color: colorScheme.surfaceContainerHighest, |
117 | borderRadius: BorderRadius.circular(8.0), |
118 | ), |
119 | ), |
120 | ), |
121 | ), |
122 | ); |
123 | } |
124 | } |
125 | |