flutter/examples/flutter_gallery/lib/demo/material/drawer_demo.dart
Ian Hickson 449f4a6673
License update (#45373)
* Update project.pbxproj files to say Flutter rather than Chromium

Also, the templates now have an empty organization so that we don't cause people to give their apps a Flutter copyright.

* Update the copyright notice checker to require a standard notice on all files

* Update copyrights on Dart files. (This was a mechanical commit.)

* Fix weird license headers on Dart files that deviate from our conventions; relicense Shrine.

Some were already marked "The Flutter Authors", not clear why. Their
dates have been normalized. Some were missing the blank line after the
license. Some were randomly different in trivial ways for no apparent
reason (e.g. missing the trailing period).

* Clean up the copyrights in non-Dart files. (Manual edits.)

Also, make sure templates don't have copyrights.

* Fix some more ORGANIZATIONNAMEs
2019-11-27 15:04:02 -08:00

267 lines
8.8 KiB
Dart

// 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/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:
case TargetPlatform.macOS:
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);
},
),
],
);
},
);
}
}