// Copyright 2018 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_web/material.dart'; import '../../gallery/demo.dart'; class DrawerDemo extends StatefulWidget { static const String routeName = '/material/drawer'; @override _DrawerDemoState createState() => _DrawerDemoState(); } class _DrawerDemoState extends State with TickerProviderStateMixin { final GlobalKey _scaffoldKey = GlobalKey(); static const List _drawerContents = [ 'A', 'B', 'C', 'D', 'E', ]; static final Animatable _drawerDetailsTween = Tween( begin: const Offset(0.0, -1.0), end: Offset.zero, ).chain(CurveTween( curve: Curves.fastOutSlowIn, )); AnimationController _controller; Animation _drawerContentsOpacity; Animation _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( key: _scaffoldKey, appBar: AppBar( leading: IconButton( icon: Icon(_backIcon()), alignment: Alignment.centerLeft, tooltip: 'Back', onPressed: () { Navigator.pop(context); }, ), title: const Text('Navigation drawer'), actions: [ MaterialDemoDocumentationButton(DrawerDemo.routeName) ], ), drawer: Drawer( child: Column( children: [ UserAccountsDrawerHeader( accountName: const Text('Trevor Widget'), accountEmail: const Text('trevor.widget@example.com'), 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( padding: const EdgeInsets.only(top: 8.0), children: [ Stack( children: [ // The initial contents of the drawer. FadeTransition( opacity: _drawerContentsOpacity, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: _drawerContents.map((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: [ 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: [ Container( width: 100.0, height: 100.0, ), Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( 'Tap here to open the drawer', style: Theme.of(context).textTheme.subhead, ), ), ], ), ), ), ), ); } }