mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

* the onStart callback will report the location of the pointer where it wins the gesture arena by default instead of the pointer down location. Fixes all tests related to changing this default value.
266 lines
8.8 KiB
Dart
266 lines
8.8 KiB
Dart
// Copyright 2016 The Chromium 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/gestures.dart' show DragStartBehavior;
|
|
|
|
import '../../gallery/demo.dart';
|
|
|
|
const String _kAsset0 = 'people/square/trevor.png';
|
|
const String _kAsset1 = 'people/square/stella.png';
|
|
const String _kAsset2 = 'people/square/sandra.png';
|
|
const String _kGalleryAssetsPackage = 'flutter_gallery_assets';
|
|
|
|
class DrawerDemo extends StatefulWidget {
|
|
static const String routeName = '/material/drawer';
|
|
|
|
@override
|
|
_DrawerDemoState createState() => _DrawerDemoState();
|
|
}
|
|
|
|
class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
|
|
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
|
|
|
static const List<String> _drawerContents = <String>[
|
|
'A', 'B', 'C', 'D', 'E',
|
|
];
|
|
|
|
static final Animatable<Offset> _drawerDetailsTween = Tween<Offset>(
|
|
begin: const Offset(0.0, -1.0),
|
|
end: Offset.zero,
|
|
).chain(CurveTween(
|
|
curve: Curves.fastOutSlowIn,
|
|
));
|
|
|
|
AnimationController _controller;
|
|
Animation<double> _drawerContentsOpacity;
|
|
Animation<Offset> _drawerDetailsPosition;
|
|
bool _showDrawerContents = true;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_controller = AnimationController(
|
|
vsync: this,
|
|
duration: const Duration(milliseconds: 200),
|
|
);
|
|
_drawerContentsOpacity = CurvedAnimation(
|
|
parent: ReverseAnimation(_controller),
|
|
curve: Curves.fastOutSlowIn,
|
|
);
|
|
_drawerDetailsPosition = _controller.drive(_drawerDetailsTween);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
IconData _backIcon() {
|
|
switch (Theme.of(context).platform) {
|
|
case TargetPlatform.android:
|
|
case TargetPlatform.fuchsia:
|
|
return Icons.arrow_back;
|
|
case TargetPlatform.iOS:
|
|
return Icons.arrow_back_ios;
|
|
}
|
|
assert(false);
|
|
return null;
|
|
}
|
|
|
|
void _showNotImplementedMessage() {
|
|
Navigator.pop(context); // Dismiss the drawer.
|
|
_scaffoldKey.currentState.showSnackBar(const SnackBar(
|
|
content: Text("The drawer's items don't do anything")
|
|
));
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
drawerDragStartBehavior: DragStartBehavior.down,
|
|
key: _scaffoldKey,
|
|
appBar: AppBar(
|
|
leading: IconButton(
|
|
icon: Icon(_backIcon()),
|
|
alignment: Alignment.centerLeft,
|
|
tooltip: 'Back',
|
|
onPressed: () {
|
|
Navigator.pop(context);
|
|
},
|
|
),
|
|
title: const Text('Navigation drawer'),
|
|
actions: <Widget>[MaterialDemoDocumentationButton(DrawerDemo.routeName)],
|
|
),
|
|
drawer: Drawer(
|
|
child: Column(
|
|
children: <Widget>[
|
|
UserAccountsDrawerHeader(
|
|
accountName: const Text('Trevor Widget'),
|
|
accountEmail: const Text('trevor.widget@example.com'),
|
|
currentAccountPicture: const CircleAvatar(
|
|
backgroundImage: AssetImage(
|
|
_kAsset0,
|
|
package: _kGalleryAssetsPackage,
|
|
),
|
|
),
|
|
otherAccountsPictures: <Widget>[
|
|
GestureDetector(
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onTap: () {
|
|
_onOtherAccountsTap(context);
|
|
},
|
|
child: Semantics(
|
|
label: 'Switch to Account B',
|
|
child: const CircleAvatar(
|
|
backgroundImage: AssetImage(
|
|
_kAsset1,
|
|
package: _kGalleryAssetsPackage,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
GestureDetector(
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onTap: () {
|
|
_onOtherAccountsTap(context);
|
|
},
|
|
child: Semantics(
|
|
label: 'Switch to Account C',
|
|
child: const CircleAvatar(
|
|
backgroundImage: AssetImage(
|
|
_kAsset2,
|
|
package: _kGalleryAssetsPackage,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
margin: EdgeInsets.zero,
|
|
onDetailsPressed: () {
|
|
_showDrawerContents = !_showDrawerContents;
|
|
if (_showDrawerContents)
|
|
_controller.reverse();
|
|
else
|
|
_controller.forward();
|
|
},
|
|
),
|
|
MediaQuery.removePadding(
|
|
context: context,
|
|
// DrawerHeader consumes top MediaQuery padding.
|
|
removeTop: true,
|
|
child: Expanded(
|
|
child: ListView(
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
padding: const EdgeInsets.only(top: 8.0),
|
|
children: <Widget>[
|
|
Stack(
|
|
children: <Widget>[
|
|
// The initial contents of the drawer.
|
|
FadeTransition(
|
|
opacity: _drawerContentsOpacity,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: _drawerContents.map<Widget>((String id) {
|
|
return ListTile(
|
|
leading: CircleAvatar(child: Text(id)),
|
|
title: Text('Drawer item $id'),
|
|
onTap: _showNotImplementedMessage,
|
|
);
|
|
}).toList(),
|
|
),
|
|
),
|
|
// The drawer's "details" view.
|
|
SlideTransition(
|
|
position: _drawerDetailsPosition,
|
|
child: FadeTransition(
|
|
opacity: ReverseAnimation(_drawerContentsOpacity),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: <Widget>[
|
|
ListTile(
|
|
leading: const Icon(Icons.add),
|
|
title: const Text('Add account'),
|
|
onTap: _showNotImplementedMessage,
|
|
),
|
|
ListTile(
|
|
leading: const Icon(Icons.settings),
|
|
title: const Text('Manage accounts'),
|
|
onTap: _showNotImplementedMessage,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
body: Center(
|
|
child: InkWell(
|
|
onTap: () {
|
|
_scaffoldKey.currentState.openDrawer();
|
|
},
|
|
child: Semantics(
|
|
button: true,
|
|
label: 'Open drawer',
|
|
excludeSemantics: true,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: <Widget>[
|
|
Container(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
decoration: const BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
image: DecorationImage(
|
|
image: AssetImage(
|
|
_kAsset0,
|
|
package: _kGalleryAssetsPackage,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 8.0),
|
|
child: Text('Tap here to open the drawer',
|
|
style: Theme.of(context).textTheme.subhead,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _onOtherAccountsTap(BuildContext context) {
|
|
showDialog<void>(
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
title: const Text('Account switching not implemented.'),
|
|
actions: <Widget>[
|
|
FlatButton(
|
|
child: const Text('OK'),
|
|
onPressed: () {
|
|
Navigator.pop(context);
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|