mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
UserAccountsDrawerHeader gallery demo, etc (#7297)
This commit is contained in:
parent
c9c577aeeb
commit
d05c7f62f2
@ -12,6 +12,7 @@ export 'colors_demo.dart';
|
|||||||
export 'data_table_demo.dart';
|
export 'data_table_demo.dart';
|
||||||
export 'date_and_time_picker_demo.dart';
|
export 'date_and_time_picker_demo.dart';
|
||||||
export 'dialog_demo.dart';
|
export 'dialog_demo.dart';
|
||||||
|
export 'drawer_demo.dart';
|
||||||
export 'expansion_panels_demo.dart';
|
export 'expansion_panels_demo.dart';
|
||||||
export 'grid_list_demo.dart';
|
export 'grid_list_demo.dart';
|
||||||
export 'icons_demo.dart';
|
export 'icons_demo.dart';
|
||||||
|
186
examples/flutter_gallery/lib/demo/drawer_demo.dart
Normal file
186
examples/flutter_gallery/lib/demo/drawer_demo.dart
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
// 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';
|
||||||
|
|
||||||
|
const String _kAsset0 = 'packages/flutter_gallery_assets/shrine/vendors/zach.jpg';
|
||||||
|
const String _kAsset1 = 'packages/flutter_gallery_assets/shrine/vendors/16c477b.jpg';
|
||||||
|
const String _kAsset2 = 'packages/flutter_gallery_assets/shrine/vendors/sandra-adams.jpg';
|
||||||
|
|
||||||
|
class DrawerDemo extends StatefulWidget {
|
||||||
|
static const String routeName = '/drawer';
|
||||||
|
|
||||||
|
@override
|
||||||
|
_DrawerDemoState createState() => new _DrawerDemoState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
|
||||||
|
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
|
static const List<String> _drawerContents = const <String>[
|
||||||
|
'A', 'B', 'C', 'D', 'E',
|
||||||
|
];
|
||||||
|
|
||||||
|
AnimationController _controller;
|
||||||
|
Animation<double> _drawerContentsOpacity;
|
||||||
|
Animation<FractionalOffset> _drawerDetailsPosition;
|
||||||
|
bool _showDrawerContents = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller = new AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
);
|
||||||
|
_drawerContentsOpacity = new CurvedAnimation(
|
||||||
|
parent: new ReverseAnimation(_controller),
|
||||||
|
curve: Curves.fastOutSlowIn,
|
||||||
|
);
|
||||||
|
_drawerDetailsPosition = new Tween<FractionalOffset>(
|
||||||
|
begin: const FractionalOffset(0.0, -1.0),
|
||||||
|
end: const FractionalOffset(0.0, 0.0),
|
||||||
|
).animate(new CurvedAnimation(
|
||||||
|
parent: _controller,
|
||||||
|
curve: Curves.fastOutSlowIn,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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.of(context).pop(); // Dismiss the drawer.
|
||||||
|
_scaffoldKey.currentState.showSnackBar(new SnackBar(
|
||||||
|
content: new Text("The drawer's items don't do anything")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return new Scaffold(
|
||||||
|
key: _scaffoldKey,
|
||||||
|
appBar: new AppBar(
|
||||||
|
leading: new IconButton(
|
||||||
|
icon: new Icon(_backIcon()),
|
||||||
|
alignment: FractionalOffset.centerLeft,
|
||||||
|
tooltip: 'Back',
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: new Text('Navigation drawer'),
|
||||||
|
),
|
||||||
|
drawer: new Drawer(
|
||||||
|
child: new Block(
|
||||||
|
children: <Widget>[
|
||||||
|
new UserAccountsDrawerHeader(
|
||||||
|
accountName: new Text('Zach Widget'),
|
||||||
|
accountEmail: new Text('zach.widget@example.com'),
|
||||||
|
currentAccountPicture: new CircleAvatar(backgroundImage: new AssetImage(_kAsset0)),
|
||||||
|
otherAccountsPictures: <Widget>[
|
||||||
|
new CircleAvatar(backgroundImage: new AssetImage(_kAsset1)),
|
||||||
|
new CircleAvatar(backgroundImage: new AssetImage(_kAsset2)),
|
||||||
|
],
|
||||||
|
onDetailsPressed: () {
|
||||||
|
_showDrawerContents = !_showDrawerContents;
|
||||||
|
if (_showDrawerContents)
|
||||||
|
_controller.reverse();
|
||||||
|
else
|
||||||
|
_controller.forward();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
new ClipRect(
|
||||||
|
child: new Stack(
|
||||||
|
children: <Widget>[
|
||||||
|
// The initial contents of the drawer.
|
||||||
|
new FadeTransition(
|
||||||
|
opacity: _drawerContentsOpacity,
|
||||||
|
child: new Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: _drawerContents.map((String id) {
|
||||||
|
return new DrawerItem(
|
||||||
|
icon: new CircleAvatar(child: new Text(id)),
|
||||||
|
child: new Text('Drawer item $id'),
|
||||||
|
onPressed: _showNotImplementedMessage,
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// The drawer's "details" view.
|
||||||
|
new SlideTransition(
|
||||||
|
position: _drawerDetailsPosition,
|
||||||
|
child: new FadeTransition(
|
||||||
|
opacity: new ReverseAnimation(_drawerContentsOpacity),
|
||||||
|
child: new Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[
|
||||||
|
new DrawerItem(
|
||||||
|
icon: new Icon(Icons.add),
|
||||||
|
child: new Text('Add account'),
|
||||||
|
onPressed: _showNotImplementedMessage,
|
||||||
|
),
|
||||||
|
new DrawerItem(
|
||||||
|
icon: new Icon(Icons.settings),
|
||||||
|
child: new Text('Manage accounts'),
|
||||||
|
onPressed: _showNotImplementedMessage,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: new Center(
|
||||||
|
child: new InkWell(
|
||||||
|
onTap: () {
|
||||||
|
_scaffoldKey.currentState.openDrawer();
|
||||||
|
},
|
||||||
|
child: new Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
new Container(
|
||||||
|
width: 100.0,
|
||||||
|
height: 100.0,
|
||||||
|
decoration: new BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
backgroundImage: new BackgroundImage(
|
||||||
|
image: new AssetImage(_kAsset0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
new Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
|
child: new Text('Tap here to open the drawer',
|
||||||
|
style: Theme.of(context).textTheme.subhead,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -102,6 +102,12 @@ final List<GalleryItem> kAllGalleryItems = <GalleryItem>[
|
|||||||
routeName: DialogDemo.routeName,
|
routeName: DialogDemo.routeName,
|
||||||
buildRoute: (BuildContext context) => new DialogDemo()
|
buildRoute: (BuildContext context) => new DialogDemo()
|
||||||
),
|
),
|
||||||
|
new GalleryItem(
|
||||||
|
title: 'Drawer',
|
||||||
|
subtitle: 'Navigation drawer with a standard header',
|
||||||
|
routeName: DrawerDemo.routeName,
|
||||||
|
buildRoute: (BuildContext context) => new DrawerDemo()
|
||||||
|
),
|
||||||
new GalleryItem(
|
new GalleryItem(
|
||||||
title: 'Expand/collapse list control',
|
title: 'Expand/collapse list control',
|
||||||
subtitle: 'List with one level of sublists',
|
subtitle: 'List with one level of sublists',
|
||||||
|
@ -33,6 +33,7 @@ final List<String> demoTitles = <String>[
|
|||||||
'Chips',
|
'Chips',
|
||||||
'Date and time pickers',
|
'Date and time pickers',
|
||||||
'Dialog',
|
'Dialog',
|
||||||
|
'Drawer',
|
||||||
'Expand/collapse list control',
|
'Expand/collapse list control',
|
||||||
'Expansion panels',
|
'Expansion panels',
|
||||||
'Floating action button',
|
'Floating action button',
|
||||||
|
@ -3,25 +3,128 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
import 'debug.dart';
|
import 'debug.dart';
|
||||||
|
|
||||||
|
class _AccountPictures extends StatelessWidget {
|
||||||
|
_AccountPictures({
|
||||||
|
Key key,
|
||||||
|
this.currentAccountPicture,
|
||||||
|
this.otherAccountsPictures,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final Widget currentAccountPicture;
|
||||||
|
final List<Widget> otherAccountsPictures;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return new Stack(
|
||||||
|
children: <Widget>[
|
||||||
|
new Positioned(
|
||||||
|
top: 0.0,
|
||||||
|
right: 0.0,
|
||||||
|
child: new Row(
|
||||||
|
children: (otherAccountsPictures ?? <Widget>[]).take(3).map((Widget picture) {
|
||||||
|
return new Container(
|
||||||
|
margin: const EdgeInsets.only(left: 16.0),
|
||||||
|
width: 40.0,
|
||||||
|
height: 40.0,
|
||||||
|
child: picture
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
new Positioned(
|
||||||
|
top: 0.0,
|
||||||
|
child: new SizedBox(
|
||||||
|
width: 72.0,
|
||||||
|
height: 72.0,
|
||||||
|
child: currentAccountPicture
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AccountDetails extends StatelessWidget {
|
||||||
|
_AccountDetails({
|
||||||
|
Key key,
|
||||||
|
this.accountName,
|
||||||
|
this.accountEmail,
|
||||||
|
this.onTap,
|
||||||
|
this.isOpen,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final Widget accountName;
|
||||||
|
final Widget accountEmail;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
final bool isOpen;
|
||||||
|
|
||||||
|
Widget addDropdownIcon(Widget line) {
|
||||||
|
final Widget icon = new Expanded(
|
||||||
|
child: new Align(
|
||||||
|
alignment: FractionalOffset.centerRight,
|
||||||
|
child: new Icon(
|
||||||
|
isOpen ? Icons.arrow_drop_up : Icons.arrow_drop_down,
|
||||||
|
color: Colors.white
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return new Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: line == null ? <Widget>[icon] : <Widget>[line, icon],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final ThemeData theme = Theme.of(context);
|
||||||
|
Widget accountNameLine = accountName == null ? null : new DefaultTextStyle(
|
||||||
|
style: theme.primaryTextTheme.body2,
|
||||||
|
child: accountName,
|
||||||
|
);
|
||||||
|
Widget accountEmailLine = accountEmail == null ? null : new DefaultTextStyle(
|
||||||
|
style: theme.primaryTextTheme.body1,
|
||||||
|
child: accountEmail,
|
||||||
|
);
|
||||||
|
if (onTap != null) {
|
||||||
|
if (accountEmailLine != null)
|
||||||
|
accountEmailLine = addDropdownIcon(accountEmailLine);
|
||||||
|
else
|
||||||
|
accountNameLine = addDropdownIcon(accountNameLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget accountDetails;
|
||||||
|
if (accountEmailLine != null || accountNameLine != null) {
|
||||||
|
accountDetails = new Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
child: new Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: (accountEmailLine != null && accountNameLine != null)
|
||||||
|
? <Widget>[accountNameLine, accountEmailLine]
|
||||||
|
: <Widget>[accountNameLine ?? accountEmailLine]
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onTap != null)
|
||||||
|
accountDetails = new InkWell(onTap: onTap, child: accountDetails);
|
||||||
|
|
||||||
|
return new SizedBox(
|
||||||
|
height: 56.0,
|
||||||
|
child: accountDetails,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A material design [Drawer] header that identifies the app's user.
|
/// A material design [Drawer] header that identifies the app's user.
|
||||||
///
|
///
|
||||||
/// The top-most region of a material design drawer with user accounts. The
|
|
||||||
/// header's [decoration] is used to provide a background.
|
|
||||||
/// [currentAccountPicture] is the main account picture on the left, while
|
|
||||||
/// [otherAccountsPictures] are the smaller account pictures on the right.
|
|
||||||
/// [accountName] and [accountEmail] provide access to the top and bottom rows
|
|
||||||
/// of the account details in the lower part of the header. When touched, this
|
|
||||||
/// area triggers [onDetailsPressed] and toggles the dropdown icon on the right.
|
|
||||||
///
|
|
||||||
/// Requires one of its ancestors to be a [Material] widget.
|
/// Requires one of its ancestors to be a [Material] widget.
|
||||||
///
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
/// * [Drawer]
|
|
||||||
/// * [DrawerHeader], for a drawer header that doesn't show user acounts
|
/// * [DrawerHeader], for a drawer header that doesn't show user acounts
|
||||||
/// * <https://material.google.com/patterns/navigation-drawer.html>
|
/// * <https://material.google.com/patterns/navigation-drawer.html>
|
||||||
class UserAccountsDrawerHeader extends StatefulWidget {
|
class UserAccountsDrawerHeader extends StatefulWidget {
|
||||||
@ -38,30 +141,31 @@ class UserAccountsDrawerHeader extends StatefulWidget {
|
|||||||
this.onDetailsPressed
|
this.onDetailsPressed
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// A callback that gets called when the account name/email/dropdown
|
/// The header's background. If decoration is null then a [BoxDecoration]
|
||||||
/// section is pressed.
|
/// with its background color set to the current theme's primaryColor is used.
|
||||||
final VoidCallback onDetailsPressed;
|
|
||||||
|
|
||||||
/// The background to show in the drawer header.
|
|
||||||
final Decoration decoration;
|
final Decoration decoration;
|
||||||
|
|
||||||
/// A widget placed in the upper-left corner representing the current
|
/// A widget placed in the upper-left corner that represents the current
|
||||||
/// account picture. Normally a [CircleAvatar].
|
/// user's account. Normally a [CircleAvatar].
|
||||||
final Widget currentAccountPicture;
|
final Widget currentAccountPicture;
|
||||||
|
|
||||||
/// A list of widgets that represent the user's accounts. Up to three of will
|
/// A list of widgets that represent the current user's other accounts.
|
||||||
/// be arranged in a row in the header's upper-right corner. Normally a list
|
/// Up to three of these widgets will be arranged in a row in the header's
|
||||||
/// of [CircleAvatar] widgets.
|
/// upper-right corner. Normally a list of [CircleAvatar] widgets.
|
||||||
final List<Widget> otherAccountsPictures;
|
final List<Widget> otherAccountsPictures;
|
||||||
|
|
||||||
/// A widget placed on the top row of the account details representing the
|
/// A widget that represents the user's current account name. It is
|
||||||
/// account's name.
|
/// displayed on the left, below the [currentAccountPicture].
|
||||||
final Widget accountName;
|
final Widget accountName;
|
||||||
|
|
||||||
/// A widget placed on the bottom row of the account details representing the
|
/// A widget that represents the email address of the user's current account.
|
||||||
/// account's e-mail address.
|
/// It is displayed on the left, below the [accountName].
|
||||||
final Widget accountEmail;
|
final Widget accountEmail;
|
||||||
|
|
||||||
|
/// A callback that is called when the horizontal area which contains the
|
||||||
|
/// [accountName] and [accountEmail] is tapped.
|
||||||
|
final VoidCallback onDetailsPressed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_UserAccountsDrawerHeaderState createState() => new _UserAccountsDrawerHeaderState();
|
_UserAccountsDrawerHeaderState createState() => new _UserAccountsDrawerHeaderState();
|
||||||
}
|
}
|
||||||
@ -72,89 +176,32 @@ class _UserAccountsDrawerHeaderState extends State<UserAccountsDrawerHeader> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
assert(debugCheckHasMaterial(context));
|
assert(debugCheckHasMaterial(context));
|
||||||
final List<Widget> otherAccountsPictures = config.otherAccountsPictures ?? <Widget>[];
|
|
||||||
return new DrawerHeader(
|
return new DrawerHeader(
|
||||||
decoration: config.decoration,
|
decoration: config.decoration ?? new BoxDecoration(
|
||||||
|
backgroundColor: Theme.of(context).primaryColor,
|
||||||
|
),
|
||||||
child: new Column(
|
child: new Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new Expanded(
|
new Expanded(
|
||||||
child: new Stack(
|
child: new _AccountPictures(
|
||||||
children: <Widget>[
|
currentAccountPicture: config.currentAccountPicture,
|
||||||
new Positioned(
|
otherAccountsPictures: config.otherAccountsPictures,
|
||||||
top: 0.0,
|
|
||||||
right: 0.0,
|
|
||||||
child: new Row(
|
|
||||||
children: otherAccountsPictures.take(3).map(
|
|
||||||
(Widget picture) {
|
|
||||||
return new Container(
|
|
||||||
margin: const EdgeInsets.only(left: 16.0),
|
|
||||||
width: 40.0,
|
|
||||||
height: 40.0,
|
|
||||||
child: picture
|
|
||||||
);
|
|
||||||
}
|
|
||||||
).toList()
|
|
||||||
)
|
|
||||||
),
|
|
||||||
new Positioned(
|
|
||||||
top: 0.0,
|
|
||||||
child: new Container(
|
|
||||||
width: 72.0,
|
|
||||||
height: 72.0,
|
|
||||||
child: config.currentAccountPicture
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new Container(
|
new _AccountDetails(
|
||||||
height: 56.0,
|
accountName: config.accountName,
|
||||||
child: new InkWell(
|
accountEmail: config.accountEmail,
|
||||||
onTap: () {
|
isOpen: _isOpen,
|
||||||
setState(() {
|
onTap: config.onDetailsPressed == null ? null : () {
|
||||||
_isOpen = !_isOpen;
|
setState(() {
|
||||||
});
|
_isOpen = !_isOpen;
|
||||||
if (config.onDetailsPressed != null)
|
});
|
||||||
config.onDetailsPressed();
|
config.onDetailsPressed();
|
||||||
},
|
},
|
||||||
child: new Container(
|
),
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
],
|
||||||
child: new Column(
|
),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
children: <Widget>[
|
|
||||||
new DefaultTextStyle(
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.white
|
|
||||||
),
|
|
||||||
child: config.accountName
|
|
||||||
),
|
|
||||||
new Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
new DefaultTextStyle(
|
|
||||||
style: const TextStyle(color: Colors.white),
|
|
||||||
child: config.accountEmail
|
|
||||||
),
|
|
||||||
new Expanded(
|
|
||||||
child: new Align(
|
|
||||||
alignment: FractionalOffset.centerRight,
|
|
||||||
child: new Icon(
|
|
||||||
_isOpen ? Icons.arrow_drop_up : Icons.arrow_drop_down,
|
|
||||||
color: Colors.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,4 +71,93 @@ void main() {
|
|||||||
expect(avatarDTopRight.y - topRight.y, equals(16.0));
|
expect(avatarDTopRight.y - topRight.y, equals(16.0));
|
||||||
expect(avatarDTopRight.x - avatarCTopRight.x, equals(40.0 + 16.0)); // size + space between
|
expect(avatarDTopRight.x - avatarCTopRight.x, equals(40.0 + 16.0)); // size + space between
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
testWidgets('UserAccountsDrawerHeader null parameters', (WidgetTester tester) async {
|
||||||
|
Widget buildFrame({
|
||||||
|
Widget currentAccountPicture,
|
||||||
|
List<Widget> otherAccountsPictures,
|
||||||
|
Widget accountName,
|
||||||
|
Widget accountEmail,
|
||||||
|
VoidCallback onDetailsPressed,
|
||||||
|
}) {
|
||||||
|
return new Material(
|
||||||
|
child: new UserAccountsDrawerHeader(
|
||||||
|
currentAccountPicture: currentAccountPicture,
|
||||||
|
otherAccountsPictures: otherAccountsPictures,
|
||||||
|
accountName: accountName,
|
||||||
|
accountEmail: accountEmail,
|
||||||
|
onDetailsPressed: onDetailsPressed,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame());
|
||||||
|
expect(find.byType(Icon), findsNothing);
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame(
|
||||||
|
onDetailsPressed: () { },
|
||||||
|
));
|
||||||
|
expect(find.byType(Icon), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame(
|
||||||
|
accountName: new Text('accountName'),
|
||||||
|
onDetailsPressed: () { },
|
||||||
|
));
|
||||||
|
expect(
|
||||||
|
tester.getCenter(find.text('accountName')).y,
|
||||||
|
tester.getCenter(find.byType(Icon)).y
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame(
|
||||||
|
accountEmail: new Text('accountEmail'),
|
||||||
|
onDetailsPressed: () { },
|
||||||
|
));
|
||||||
|
expect(
|
||||||
|
tester.getCenter(find.text('accountEmail')).y,
|
||||||
|
tester.getCenter(find.byType(Icon)).y
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame(
|
||||||
|
accountName: new Text('accountName'),
|
||||||
|
accountEmail: new Text('accountEmail'),
|
||||||
|
onDetailsPressed: () { },
|
||||||
|
));
|
||||||
|
expect(
|
||||||
|
tester.getCenter(find.text('accountEmail')).y,
|
||||||
|
tester.getCenter(find.byType(Icon)).y
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester.getBottomLeft(find.text('accountEmail')).y,
|
||||||
|
greaterThan(tester.getBottomLeft(find.text('accountName')).y)
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester.getBottomLeft(find.text('accountEmail')).x,
|
||||||
|
tester.getBottomLeft(find.text('accountName')).x
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame(
|
||||||
|
currentAccountPicture: new CircleAvatar(child: new Text('A')),
|
||||||
|
));
|
||||||
|
expect(find.text('A'), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame(
|
||||||
|
otherAccountsPictures: <Widget>[new CircleAvatar(child: new Text('A'))],
|
||||||
|
));
|
||||||
|
expect(find.text('A'), findsOneWidget);
|
||||||
|
|
||||||
|
final Key avatarA = new Key('A');
|
||||||
|
await tester.pumpWidget(buildFrame(
|
||||||
|
currentAccountPicture: new CircleAvatar(key: avatarA, child: new Text('A')),
|
||||||
|
accountName: new Text('accountName'),
|
||||||
|
));
|
||||||
|
expect(
|
||||||
|
tester.getBottomLeft(find.byKey(avatarA)).x,
|
||||||
|
tester.getBottomLeft(find.text('accountName')).x
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
tester.getBottomLeft(find.text('accountName')).y,
|
||||||
|
greaterThan(tester.getBottomLeft(find.byKey(avatarA)).y)
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user