blob: f904102678b41d14fef629fb9f075cdb83774e7d [file] [log] [blame]
// 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.surfaceContainerHighest,
borderRadius: BorderRadius.circular(8.0),
),
),
),
),
);
}
}