mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
This reverts the change to `user_accounts_drawer_header.dart` (and the associated test), as it was causing regressions in layout of the drawer header. https://github.com/flutter/flutter/issues/13743
This commit is contained in:
parent
36bd9ee0d4
commit
7132083b24
@ -10,7 +10,6 @@ import 'debug.dart';
|
|||||||
import 'drawer_header.dart';
|
import 'drawer_header.dart';
|
||||||
import 'icons.dart';
|
import 'icons.dart';
|
||||||
import 'ink_well.dart';
|
import 'ink_well.dart';
|
||||||
import 'material_localizations.dart';
|
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
|
|
||||||
class _AccountPictures extends StatelessWidget {
|
class _AccountPictures extends StatelessWidget {
|
||||||
@ -36,10 +35,7 @@ class _AccountPictures extends StatelessWidget {
|
|||||||
margin: const EdgeInsetsDirectional.only(start: 16.0),
|
margin: const EdgeInsetsDirectional.only(start: 16.0),
|
||||||
width: 40.0,
|
width: 40.0,
|
||||||
height: 40.0,
|
height: 40.0,
|
||||||
child: new Semantics(
|
child: picture
|
||||||
container: true,
|
|
||||||
child: picture,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
@ -49,7 +45,7 @@ class _AccountPictures extends StatelessWidget {
|
|||||||
child: new SizedBox(
|
child: new SizedBox(
|
||||||
width: 72.0,
|
width: 72.0,
|
||||||
height: 72.0,
|
height: 72.0,
|
||||||
child: currentAccountPicture,
|
child: currentAccountPicture
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -71,72 +67,62 @@ class _AccountDetails extends StatelessWidget {
|
|||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final bool isOpen;
|
final bool isOpen;
|
||||||
|
|
||||||
|
Widget addDropdownIcon(Widget line) {
|
||||||
|
final Widget icon = new Icon(
|
||||||
|
isOpen ? Icons.arrow_drop_up : Icons.arrow_drop_down,
|
||||||
|
color: Colors.white
|
||||||
|
);
|
||||||
|
return new Expanded(
|
||||||
|
child: new Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: line == null ? <Widget>[icon] : <Widget>[
|
||||||
|
new Expanded(child: line),
|
||||||
|
icon,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ThemeData theme = Theme.of(context);
|
final ThemeData theme = Theme.of(context);
|
||||||
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
|
Widget accountNameLine = accountName == null ? null : new DefaultTextStyle(
|
||||||
final Widget accountNameLine = accountName == null ? null : new DefaultTextStyle(
|
|
||||||
style: theme.primaryTextTheme.body2,
|
style: theme.primaryTextTheme.body2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
child: accountName,
|
child: accountName,
|
||||||
);
|
);
|
||||||
final Widget accountEmailLine = accountEmail == null ? null : new DefaultTextStyle(
|
Widget accountEmailLine = accountEmail == null ? null : new DefaultTextStyle(
|
||||||
style: theme.primaryTextTheme.body1,
|
style: theme.primaryTextTheme.body1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
child: accountEmail,
|
child: accountEmail,
|
||||||
);
|
);
|
||||||
|
if (onTap != null) {
|
||||||
|
if (accountEmailLine != null)
|
||||||
|
accountEmailLine = addDropdownIcon(accountEmailLine);
|
||||||
|
else
|
||||||
|
accountNameLine = addDropdownIcon(accountNameLine);
|
||||||
|
}
|
||||||
|
|
||||||
final List<Widget> rowChildren = <Widget>[];
|
Widget accountDetails;
|
||||||
|
|
||||||
if (accountEmailLine != null || accountNameLine != null) {
|
if (accountEmailLine != null || accountNameLine != null) {
|
||||||
rowChildren.add(
|
accountDetails = new Padding(
|
||||||
new Expanded(
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
flex: 1,
|
|
||||||
child: new Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(16.0, 8.0, 0.0, 8.0),
|
|
||||||
child: new Column(
|
child: new Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: (accountEmailLine != null && accountNameLine != null)
|
children: (accountEmailLine != null && accountNameLine != null)
|
||||||
? <Widget>[accountNameLine, accountEmailLine]
|
? <Widget>[accountNameLine, accountEmailLine]
|
||||||
: <Widget>[accountNameLine ?? accountEmailLine],
|
: <Widget>[accountNameLine ?? accountEmailLine]
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double kAccountDetailsHeight = 56.0;
|
if (onTap != null)
|
||||||
|
accountDetails = new InkWell(onTap: onTap, child: accountDetails);
|
||||||
if (onTap != null) {
|
|
||||||
rowChildren.add(
|
|
||||||
new InkWell(
|
|
||||||
onTap: onTap,
|
|
||||||
child: new Semantics(
|
|
||||||
button: true,
|
|
||||||
child: new SizedBox(
|
|
||||||
height: kAccountDetailsHeight,
|
|
||||||
width: kAccountDetailsHeight, // make it a square
|
|
||||||
child: new Center(
|
|
||||||
child: new Icon(
|
|
||||||
isOpen ? Icons.arrow_drop_up : Icons.arrow_drop_down,
|
|
||||||
color: Colors.white,
|
|
||||||
semanticLabel: isOpen
|
|
||||||
? localizations.hideAccountsLabel
|
|
||||||
: localizations.showAccountsLabel,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SizedBox(
|
return new SizedBox(
|
||||||
height: kAccountDetailsHeight,
|
height: 56.0,
|
||||||
child: new Row(
|
child: accountDetails,
|
||||||
children: rowChildren,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,7 +147,7 @@ class UserAccountsDrawerHeader extends StatefulWidget {
|
|||||||
this.otherAccountsPictures,
|
this.otherAccountsPictures,
|
||||||
@required this.accountName,
|
@required this.accountName,
|
||||||
@required this.accountEmail,
|
@required this.accountEmail,
|
||||||
this.onDetailsPressed,
|
this.onDetailsPressed
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// The header's background. If decoration is null then a [BoxDecoration]
|
/// The header's background. If decoration is null then a [BoxDecoration]
|
||||||
@ -214,23 +200,16 @@ class _UserAccountsDrawerHeaderState extends State<UserAccountsDrawerHeader> {
|
|||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
),
|
),
|
||||||
margin: widget.margin,
|
margin: widget.margin,
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
child: new SafeArea(
|
child: new SafeArea(
|
||||||
bottom: false,
|
bottom: false,
|
||||||
child: new Semantics(
|
|
||||||
container: true,
|
|
||||||
label: 'Signed in',
|
|
||||||
child: new Column(
|
child: new Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new Expanded(
|
new Expanded(
|
||||||
child: new Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
|
|
||||||
child: new _AccountPictures(
|
child: new _AccountPictures(
|
||||||
currentAccountPicture: widget.currentAccountPicture,
|
currentAccountPicture: widget.currentAccountPicture,
|
||||||
otherAccountsPictures: widget.otherAccountsPictures,
|
otherAccountsPictures: widget.otherAccountsPictures,
|
||||||
),
|
)
|
||||||
),
|
|
||||||
),
|
),
|
||||||
new _AccountDetails(
|
new _AccountDetails(
|
||||||
accountName: widget.accountName,
|
accountName: widget.accountName,
|
||||||
@ -241,7 +220,6 @@ class _UserAccountsDrawerHeaderState extends State<UserAccountsDrawerHeader> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,16 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart' hide TypeMatcher;
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import '../widgets/semantics_tester.dart';
|
void main() {
|
||||||
|
testWidgets('UserAccountsDrawerHeader test', (WidgetTester tester) async {
|
||||||
|
final Key avatarA = const Key('A');
|
||||||
|
final Key avatarC = const Key('C');
|
||||||
|
final Key avatarD = const Key('D');
|
||||||
|
|
||||||
const Key avatarA = const Key('A');
|
|
||||||
const Key avatarC = const Key('C');
|
|
||||||
const Key avatarD = const Key('D');
|
|
||||||
|
|
||||||
Future<Null> pumpTestWidget(WidgetTester tester, {
|
|
||||||
bool withName: true,
|
|
||||||
bool withEmail: true,
|
|
||||||
bool withOnDetailsPressedHandler: true,
|
|
||||||
}) async {
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new MaterialApp(
|
new MaterialApp(
|
||||||
home: new MediaQuery(
|
home: new MediaQuery(
|
||||||
@ -33,8 +26,7 @@ Future<Null> pumpTestWidget(WidgetTester tester, {
|
|||||||
child: new Material(
|
child: new Material(
|
||||||
child: new Center(
|
child: new Center(
|
||||||
child: new UserAccountsDrawerHeader(
|
child: new UserAccountsDrawerHeader(
|
||||||
onDetailsPressed: withOnDetailsPressedHandler ? () {} : null,
|
currentAccountPicture: new CircleAvatar(
|
||||||
currentAccountPicture: const CircleAvatar(
|
|
||||||
key: avatarA,
|
key: avatarA,
|
||||||
child: const Text('A'),
|
child: const Text('A'),
|
||||||
),
|
),
|
||||||
@ -42,11 +34,11 @@ Future<Null> pumpTestWidget(WidgetTester tester, {
|
|||||||
const CircleAvatar(
|
const CircleAvatar(
|
||||||
child: const Text('B'),
|
child: const Text('B'),
|
||||||
),
|
),
|
||||||
const CircleAvatar(
|
new CircleAvatar(
|
||||||
key: avatarC,
|
key: avatarC,
|
||||||
child: const Text('C'),
|
child: const Text('C'),
|
||||||
),
|
),
|
||||||
const CircleAvatar(
|
new CircleAvatar(
|
||||||
key: avatarD,
|
key: avatarD,
|
||||||
child: const Text('D'),
|
child: const Text('D'),
|
||||||
),
|
),
|
||||||
@ -54,19 +46,14 @@ Future<Null> pumpTestWidget(WidgetTester tester, {
|
|||||||
child: const Text('E'),
|
child: const Text('E'),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
accountName: withName ? const Text('name') : null,
|
accountName: const Text('name'),
|
||||||
accountEmail: withEmail ? const Text('email') : null,
|
accountEmail: const Text('email'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWidgets('UserAccountsDrawerHeader layout', (WidgetTester tester) async {
|
|
||||||
await pumpTestWidget(tester);
|
|
||||||
|
|
||||||
expect(find.text('A'), findsOneWidget);
|
expect(find.text('A'), findsOneWidget);
|
||||||
expect(find.text('B'), findsOneWidget);
|
expect(find.text('B'), findsOneWidget);
|
||||||
@ -139,8 +126,6 @@ void main() {
|
|||||||
));
|
));
|
||||||
expect(find.byType(Icon), findsOneWidget);
|
expect(find.byType(Icon), findsOneWidget);
|
||||||
|
|
||||||
// When either email or account name (but not both!) are present, the icon
|
|
||||||
// is center aligned with the text displaying the email/name.
|
|
||||||
await tester.pumpWidget(buildFrame(
|
await tester.pumpWidget(buildFrame(
|
||||||
accountName: const Text('accountName'),
|
accountName: const Text('accountName'),
|
||||||
onDetailsPressed: () { },
|
onDetailsPressed: () { },
|
||||||
@ -159,16 +144,13 @@ void main() {
|
|||||||
tester.getCenter(find.byType(Icon)).dy
|
tester.getCenter(find.byType(Icon)).dy
|
||||||
);
|
);
|
||||||
|
|
||||||
// When _both_ email and account name are present, the icon is placed in the
|
|
||||||
// center of the entire row. It's not aligned with text any more.
|
|
||||||
await tester.pumpWidget(buildFrame(
|
await tester.pumpWidget(buildFrame(
|
||||||
accountName: const Text('accountName'),
|
accountName: const Text('accountName'),
|
||||||
accountEmail: const Text('accountEmail'),
|
accountEmail: const Text('accountEmail'),
|
||||||
onDetailsPressed: () { },
|
onDetailsPressed: () { },
|
||||||
));
|
));
|
||||||
final RenderFlex row = tester.element(find.text('accountEmail')).ancestorRenderObjectOfType(const TypeMatcher<RenderFlex>());
|
|
||||||
expect(
|
expect(
|
||||||
row.localToGlobal(row.size.center(Offset.zero)).dy,
|
tester.getCenter(find.text('accountEmail')).dy,
|
||||||
tester.getCenter(find.byType(Icon)).dy
|
tester.getCenter(find.byType(Icon)).dy
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
@ -204,83 +186,4 @@ void main() {
|
|||||||
greaterThan(tester.getBottomLeft(find.byKey(avatarA)).dy)
|
greaterThan(tester.getBottomLeft(find.byKey(avatarA)).dy)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('UserAccountsDrawerHeader provides semantics', (WidgetTester tester) async {
|
|
||||||
final SemanticsTester semantics = new SemanticsTester(tester);
|
|
||||||
await pumpTestWidget(tester);
|
|
||||||
expect(
|
|
||||||
semantics,
|
|
||||||
hasSemantics(
|
|
||||||
new TestSemantics(
|
|
||||||
children: <TestSemantics>[
|
|
||||||
new TestSemantics(
|
|
||||||
label: 'Signed in\nA\nname\nemail',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
children: <TestSemantics>[
|
|
||||||
new TestSemantics(
|
|
||||||
label: r'B',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
),
|
|
||||||
new TestSemantics(
|
|
||||||
label: r'C',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
),
|
|
||||||
new TestSemantics(
|
|
||||||
label: r'D',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
),
|
|
||||||
new TestSemantics(
|
|
||||||
flags: <SemanticsFlags>[SemanticsFlags.isButton],
|
|
||||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
|
||||||
label: r'Show accounts',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
ignoreId: true, ignoreTransform: true, ignoreRect: true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
semantics.dispose();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('UserAccountsDrawerHeader provides semantics with missing properties', (WidgetTester tester) async {
|
|
||||||
final SemanticsTester semantics = new SemanticsTester(tester);
|
|
||||||
await pumpTestWidget(
|
|
||||||
tester,
|
|
||||||
withEmail: false,
|
|
||||||
withName: false,
|
|
||||||
withOnDetailsPressedHandler: false,
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
semantics,
|
|
||||||
hasSemantics(
|
|
||||||
new TestSemantics(
|
|
||||||
children: <TestSemantics>[
|
|
||||||
new TestSemantics(
|
|
||||||
label: 'Signed in\nA',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
children: <TestSemantics>[
|
|
||||||
new TestSemantics(
|
|
||||||
label: r'B',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
),
|
|
||||||
new TestSemantics(
|
|
||||||
label: r'C',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
),
|
|
||||||
new TestSemantics(
|
|
||||||
label: r'D',
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
ignoreId: true, ignoreTransform: true, ignoreRect: true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
semantics.dispose();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user