1
0
mirror of https://github.com/flutter/samples.git synced 2026-04-05 11:11:23 +00:00

Update gallery, fix Cupertino fonts by using GoogleSans instead (#155)

* Update gallery, fix Cupertino fonts

Cupertino fonts fixed by using GoogleSans instead

* remove BUILD.gn

* remove ios and android dirs from web/gallery

* remove meta/flutter_gallery.cmx

* revert provider_shopper/pubspec.lock

* remove gallery's test and tool directories

* update web/gallery README
This commit is contained in:
John Ryan
2019-10-28 14:33:43 -07:00
committed by GitHub
parent 2af51a8222
commit a29853144b
29 changed files with 692 additions and 683 deletions

View File

@@ -302,8 +302,9 @@ class CalcExpression {
assert(false);
}
}
final List<ExpressionToken> outList = <ExpressionToken>[];
outList.add(ResultToken(currentTermValue));
final List<ExpressionToken> outList = <ExpressionToken>[
ResultToken(currentTermValue),
];
return CalcExpression(outList, ExpressionState.Result);
}

View File

@@ -117,7 +117,7 @@ class PaletteTabView extends StatelessWidget {
);
}),
],
)
),
);
}
}

View File

@@ -54,33 +54,31 @@ class _ContactItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final List<Widget> columnChildren = lines.sublist(0, lines.length - 1).map<Widget>((String line) => Text(line)).toList();
columnChildren.add(Text(lines.last, style: themeData.textTheme.caption));
final List<Widget> rowChildren = <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: columnChildren,
),
),
];
if (icon != null) {
rowChildren.add(SizedBox(
width: 72.0,
child: IconButton(
icon: Icon(icon),
color: themeData.primaryColor,
onPressed: onPressed,
),
));
}
return MergeSemantics(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: rowChildren,
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
...lines.sublist(0, lines.length - 1).map<Widget>((String line) => Text(line)),
Text(lines.last, style: themeData.textTheme.caption),
],
),
),
if (icon != null)
SizedBox(
width: 72.0,
child: IconButton(
icon: Icon(icon),
color: themeData.primaryColor,
onPressed: onPressed,
),
),
],
),
),
);

View File

@@ -53,159 +53,146 @@ class _CupertinoAlertDemoState extends State<CupertinoAlertDemo> {
style: CupertinoTheme.of(context).textTheme.textStyle,
child: Builder(
builder: (BuildContext context) {
final List<Widget> stackChildren = <Widget>[
CupertinoScrollbar(
child: ListView(
// Add more padding to the normal safe area.
padding: const EdgeInsets.symmetric(vertical: 24.0, horizontal: 72.0)
+ MediaQuery.of(context).padding,
children: <Widget>[
CupertinoButton.filled(
child: const Text('Alert'),
onPressed: () {
showDemoDialog(
context: context,
child: CupertinoAlertDialog(
title: const Text('Discard draft?'),
actions: <Widget>[
CupertinoDialogAction(
child: const Text('Discard'),
isDestructiveAction: true,
onPressed: () {
Navigator.pop(context, 'Discard');
},
),
CupertinoDialogAction(
child: const Text('Cancel'),
isDefaultAction: true,
onPressed: () {
Navigator.pop(context, 'Cancel');
},
),
],
),
);
},
),
const Padding(padding: EdgeInsets.all(8.0)),
CupertinoButton.filled(
child: const Text('Alert with Title'),
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 36.0),
onPressed: () {
showDemoDialog(
context: context,
child: CupertinoAlertDialog(
title: const Text('Allow "Maps" to access your location while you are using the app?'),
content: const Text('Your current location will be displayed on the map and used '
'for directions, nearby search results, and estimated travel times.'),
actions: <Widget>[
CupertinoDialogAction(
child: const Text('Don\'t Allow'),
onPressed: () {
Navigator.pop(context, 'Disallow');
},
),
CupertinoDialogAction(
child: const Text('Allow'),
onPressed: () {
Navigator.pop(context, 'Allow');
},
),
],
),
);
},
),
const Padding(padding: EdgeInsets.all(8.0)),
CupertinoButton.filled(
child: const Text('Alert with Buttons'),
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 36.0),
onPressed: () {
showDemoDialog(
context: context,
child: const CupertinoDessertDialog(
title: Text('Select Favorite Dessert'),
content: Text('Please select your favorite type of dessert from the '
'list below. Your selection will be used to customize the suggested '
'list of eateries in your area.'),
),
);
},
),
const Padding(padding: EdgeInsets.all(8.0)),
CupertinoButton.filled(
child: const Text('Alert Buttons Only'),
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 36.0),
onPressed: () {
showDemoDialog(
context: context,
child: const CupertinoDessertDialog(),
);
},
),
const Padding(padding: EdgeInsets.all(8.0)),
CupertinoButton.filled(
child: const Text('Action Sheet'),
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 36.0),
onPressed: () {
showDemoActionSheet(
context: context,
child: CupertinoActionSheet(
title: const Text('Favorite Dessert'),
message: const Text('Please select the best dessert from the options below.'),
actions: <Widget>[
CupertinoActionSheetAction(
child: const Text('Profiteroles'),
onPressed: () {
Navigator.pop(context, 'Profiteroles');
},
),
CupertinoActionSheetAction(
child: const Text('Cannolis'),
onPressed: () {
Navigator.pop(context, 'Cannolis');
},
),
CupertinoActionSheetAction(
child: const Text('Trifle'),
onPressed: () {
Navigator.pop(context, 'Trifle');
},
),
],
cancelButton: CupertinoActionSheetAction(
child: const Text('Cancel'),
isDefaultAction: true,
onPressed: () {
Navigator.pop(context, 'Cancel');
},
),
),
);
},
),
],
),
),
];
if (lastSelectedValue != null) {
stackChildren.add(
Positioned(
bottom: 32.0,
child: Text('You selected: $lastSelectedValue'),
),
);
}
return Stack(
alignment: Alignment.center,
children: stackChildren,
children: <Widget>[
CupertinoScrollbar(
child: ListView(
// Add more padding to the normal safe area.
padding: const EdgeInsets.symmetric(vertical: 24.0, horizontal: 72.0)
+ MediaQuery.of(context).padding,
children: <Widget>[
CupertinoButton.filled(
child: const Text('Alert'),
onPressed: () => _onAlertPress(context),
),
const Padding(padding: EdgeInsets.all(8.0)),
CupertinoButton.filled(
child: const Text('Alert with Title'),
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 36.0),
onPressed: () => _onAlertWithTitlePress(context),
),
const Padding(padding: EdgeInsets.all(8.0)),
CupertinoButton.filled(
child: const Text('Alert with Buttons'),
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 36.0),
onPressed: () => _onAlertWithButtonsPress(context),
),
const Padding(padding: EdgeInsets.all(8.0)),
CupertinoButton.filled(
child: const Text('Alert Buttons Only'),
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 36.0),
onPressed: () {
showDemoDialog(
context: context,
child: const CupertinoDessertDialog(),
);
},
),
const Padding(padding: EdgeInsets.all(8.0)),
CupertinoButton.filled(
child: const Text('Action Sheet'),
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 36.0),
onPressed: () => _onActionSheetPress(context),
),
],
),
),
if (lastSelectedValue != null)
Positioned(
bottom: 32.0,
child: Text('You selected: $lastSelectedValue'),
),
],
);
},
),
),
);
}
void _onAlertPress(BuildContext context) {
showDemoDialog(
context: context,
child: CupertinoAlertDialog(
title: const Text('Discard draft?'),
actions: <Widget>[
CupertinoDialogAction(
child: const Text('Discard'),
isDestructiveAction: true,
onPressed: () => Navigator.pop(context, 'Discard'),
),
CupertinoDialogAction(
child: const Text('Cancel'),
isDefaultAction: true,
onPressed: () => Navigator.pop(context, 'Cancel'),
),
],
),
);
}
void _onAlertWithTitlePress(BuildContext context) {
showDemoDialog(
context: context,
child: CupertinoAlertDialog(
title: const Text('Allow "Maps" to access your location while you are using the app?'),
content: const Text('Your current location will be displayed on the map and used '
'for directions, nearby search results, and estimated travel times.'),
actions: <Widget>[
CupertinoDialogAction(
child: const Text('Don\'t Allow'),
onPressed: () => Navigator.pop(context, 'Disallow'),
),
CupertinoDialogAction(
child: const Text('Allow'),
onPressed: () => Navigator.pop(context, 'Allow'),
),
],
),
);
}
void _onAlertWithButtonsPress(BuildContext context) {
showDemoDialog(
context: context,
child: const CupertinoDessertDialog(
title: Text('Select Favorite Dessert'),
content: Text('Please select your favorite type of dessert from the '
'list below. Your selection will be used to customize the suggested '
'list of eateries in your area.'),
),
);
}
void _onActionSheetPress(BuildContext context) {
showDemoActionSheet(
context: context,
child: CupertinoActionSheet(
title: const Text('Favorite Dessert'),
message: const Text('Please select the best dessert from the options below.'),
actions: <Widget>[
CupertinoActionSheetAction(
child: const Text('Profiteroles'),
onPressed: () => Navigator.pop(context, 'Profiteroles'),
),
CupertinoActionSheetAction(
child: const Text('Cannolis'),
onPressed: () => Navigator.pop(context, 'Cannolis'),
),
CupertinoActionSheetAction(
child: const Text('Trifle'),
onPressed: () => Navigator.pop(context, 'Trifle'),
),
],
cancelButton: CupertinoActionSheetAction(
child: const Text('Cancel'),
isDefaultAction: true,
onPressed: () => Navigator.pop(context, 'Cancel'),
),
),
);
}
}
class CupertinoDessertDialog extends StatelessWidget {

View File

@@ -647,25 +647,21 @@ class Tab2ConversationRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final List<Widget> children = <Widget>[];
if (avatar != null)
children.add(avatar);
final bool isSelf = avatar == null;
children.add(
Tab2ConversationBubble(
text: text,
color: isSelf
? Tab2ConversationBubbleColor.blue
: Tab2ConversationBubbleColor.gray,
),
);
return SafeArea(
child: Row(
mainAxisAlignment: isSelf ? MainAxisAlignment.end : MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: isSelf ? CrossAxisAlignment.center : CrossAxisAlignment.end,
children: children,
children: <Widget>[
if (avatar != null) avatar,
Tab2ConversationBubble(
text: text,
color: isSelf
? Tab2ConversationBubbleColor.blue
: Tab2ConversationBubbleColor.gray,
),
],
),
);
}

View File

@@ -139,7 +139,7 @@ class FruitPage extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 16),
child: Row(
children: <Widget>[
CircleAvatar(
const CircleAvatar(
backgroundImage: ExactAssetImage(
'people/square/trevor.png',
package: 'flutter_gallery_assets',

View File

@@ -140,7 +140,7 @@ class CategoryView extends StatelessWidget {
],
);
}).toList(),
)
),
);
}
}

View File

@@ -57,7 +57,7 @@ class _BannerDemoState extends State<BannerDemo> {
setState(() {
_displayBanner = false;
});
}
},
),
if (_showMultipleActions)
FlatButton(
@@ -66,7 +66,7 @@ class _BannerDemoState extends State<BannerDemo> {
setState(() {
_displayBanner = false;
});
}
},
),
],
);

View File

@@ -164,10 +164,9 @@ class _BottomNavigationDemoState extends State<BottomNavigationDemo>
}
Widget _buildTransitionsStack() {
final List<FadeTransition> transitions = <FadeTransition>[];
for (NavigationIconView view in _navigationViews)
transitions.add(view.transition(_type, context));
final List<FadeTransition> transitions = <FadeTransition>[
for (NavigationIconView view in _navigationViews) view.transition(_type, context),
];
// We want to have the newly animating (fading in) views on top.
transitions.sort((FadeTransition a, FadeTransition b) {

View File

@@ -262,89 +262,83 @@ class TravelDestinationContent extends StatelessWidget {
final TextStyle titleStyle = theme.textTheme.headline.copyWith(color: Colors.white);
final TextStyle descriptionStyle = theme.textTheme.subhead;
final List<Widget> children = <Widget>[
// Photo and title.
SizedBox(
height: 184.0,
child: Stack(
children: <Widget>[
Positioned.fill(
// In order to have the ink splash appear above the image, you
// must use Ink.image. This allows the image to be painted as part
// of the Material and display ink effects above it. Using a
// standard Image will obscure the ink splash.
child: Ink.image(
image: AssetImage(destination.assetName, package: destination.assetPackage),
fit: BoxFit.cover,
child: Container(),
),
),
Positioned(
bottom: 16.0,
left: 16.0,
right: 16.0,
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Text(
destination.title,
style: titleStyle,
),
),
),
],
),
),
// Description and share/explore buttons.
Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: DefaultTextStyle(
softWrap: false,
overflow: TextOverflow.ellipsis,
style: descriptionStyle,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// Photo and title.
SizedBox(
height: 184.0,
child: Stack(
children: <Widget>[
// three line description
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
destination.description,
style: descriptionStyle.copyWith(color: Colors.black54),
Positioned.fill(
// In order to have the ink splash appear above the image, you
// must use Ink.image. This allows the image to be painted as part
// of the Material and display ink effects above it. Using a
// standard Image will obscure the ink splash.
child: Ink.image(
image: AssetImage(destination.assetName, package: destination.assetPackage),
fit: BoxFit.cover,
child: Container(),
),
),
Positioned(
bottom: 16.0,
left: 16.0,
right: 16.0,
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Text(
destination.title,
style: titleStyle,
),
),
),
Text(destination.city),
Text(destination.location),
],
),
),
),
];
if (destination.type == CardDemoType.standard) {
children.add(
// share, explore buttons
ButtonBar(
alignment: MainAxisAlignment.start,
children: <Widget>[
FlatButton(
child: Text('SHARE', semanticsLabel: 'Share ${destination.title}'),
textColor: Colors.amber.shade500,
onPressed: () { print('pressed'); },
// Description and share/explore buttons.
Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: DefaultTextStyle(
softWrap: false,
overflow: TextOverflow.ellipsis,
style: descriptionStyle,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// three line description
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
destination.description,
style: descriptionStyle.copyWith(color: Colors.black54),
),
),
Text(destination.city),
Text(destination.location),
],
),
FlatButton(
child: Text('EXPLORE', semanticsLabel: 'Explore ${destination.title}'),
textColor: Colors.amber.shade500,
onPressed: () { print('pressed'); },
),
],
),
),
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
if (destination.type == CardDemoType.standard)
// share, explore buttons
ButtonBar(
alignment: MainAxisAlignment.start,
children: <Widget>[
FlatButton(
child: Text('SHARE', semanticsLabel: 'Share ${destination.title}'),
textColor: Colors.amber.shade500,
onPressed: () { print('pressed'); },
),
FlatButton(
child: Text('EXPLORE', semanticsLabel: 'Explore ${destination.title}'),
textColor: Colors.amber.shade500,
onPressed: () { print('pressed'); },
),
],
),
],
);
}
}

View File

@@ -83,40 +83,36 @@ class _ChipsTile extends StatelessWidget {
// Wraps a list of chips into a ListTile for display as a section in the demo.
@override
Widget build(BuildContext context) {
final List<Widget> cardChildren = <Widget>[
Container(
padding: const EdgeInsets.only(top: 16.0, bottom: 4.0),
alignment: Alignment.center,
child: Text(label, textAlign: TextAlign.start),
),
];
if (children.isNotEmpty) {
cardChildren.add(Wrap(
children: children.map<Widget>((Widget chip) {
return Padding(
padding: const EdgeInsets.all(2.0),
child: chip,
);
}).toList()));
} else {
final TextStyle textStyle = Theme.of(context).textTheme.caption.copyWith(fontStyle: FontStyle.italic);
cardChildren.add(
Semantics(
container: true,
child: Container(
alignment: Alignment.center,
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
padding: const EdgeInsets.all(8.0),
child: Text('None', style: textStyle),
),
));
}
return Card(
semanticContainer: false,
child: Column(
mainAxisSize: MainAxisSize.min,
children: cardChildren,
children: <Widget>[
Container(
padding: const EdgeInsets.only(top: 16.0, bottom: 4.0),
alignment: Alignment.center,
child: Text(label, textAlign: TextAlign.start),
),
if (children.isNotEmpty)
Wrap(
children: children.map<Widget>((Widget chip) {
return Padding(
padding: const EdgeInsets.all(2.0),
child: chip,
);
}).toList(),
)
else
Semantics(
container: true,
child: Container(
alignment: Alignment.center,
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
padding: const EdgeInsets.all(8.0),
child: Text('None', style: Theme.of(context).textTheme.caption.copyWith(fontStyle: FontStyle.italic)),
),
),
],
),
);
}

View File

@@ -245,14 +245,18 @@ class _LeaveBehindListItem extends StatelessWidget {
},
background: Container(
color: theme.primaryColor,
child: const ListTile(
leading: Icon(Icons.delete, color: Colors.white, size: 36.0),
child: const Center(
child: ListTile(
leading: Icon(Icons.delete, color: Colors.white, size: 36.0),
),
),
),
secondaryBackground: Container(
color: theme.primaryColor,
child: const ListTile(
trailing: Icon(Icons.archive, color: Colors.white, size: 36.0),
child: const Center(
child: ListTile(
trailing: Icon(Icons.archive, color: Colors.white, size: 36.0),
),
),
),
child: Container(

View File

@@ -204,22 +204,23 @@ class _SearchDemoSearchDelegate extends SearchDelegate<int> {
@override
List<Widget> buildActions(BuildContext context) {
return <Widget>[
query.isEmpty
? IconButton(
tooltip: 'Voice Search',
icon: const Icon(Icons.mic),
onPressed: () {
query = 'TODO: implement voice input';
},
)
: IconButton(
tooltip: 'Clear',
icon: const Icon(Icons.clear),
onPressed: () {
query = '';
showSuggestions(context);
},
),
if (query.isEmpty)
IconButton(
tooltip: 'Voice Search',
icon: const Icon(Icons.mic),
onPressed: () {
query = 'TODO: implement voice input';
},
)
else
IconButton(
tooltip: 'Clear',
icon: const Icon(Icons.clear),
onPressed: () {
query = '';
showSuggestions(context);
},
),
];
}
}

View File

@@ -88,7 +88,7 @@ class _SnackBarDemoState extends State<SnackBarDemo> {
tooltip: 'Create',
onPressed: () {
print('Floating Action Button was pressed');
}
},
),
);
}

View File

@@ -22,6 +22,65 @@ const Cubic _kDecelerateCurve = Cubic(0.23, 0.94, 0.41, 1.0);
const double _kPeakVelocityTime = 0.248210;
const double _kPeakVelocityProgress = 0.379146;
class _TappableWhileStatusIs extends StatefulWidget {
const _TappableWhileStatusIs(
this.status, {
Key key,
this.controller,
this.child,
}) : super(key: key);
final AnimationController controller;
final AnimationStatus status;
final Widget child;
@override
_TappableWhileStatusIsState createState() => _TappableWhileStatusIsState();
}
class _TappableWhileStatusIsState extends State<_TappableWhileStatusIs> {
bool _active;
@override
void initState() {
super.initState();
widget.controller.addStatusListener(_handleStatusChange);
_active = widget.controller.status == widget.status;
}
@override
void dispose() {
widget.controller.removeStatusListener(_handleStatusChange);
super.dispose();
}
void _handleStatusChange(AnimationStatus status) {
final bool value = widget.controller.status == widget.status;
if (_active != value) {
setState(() {
_active = value;
});
}
}
@override
Widget build(BuildContext context) {
Widget child = AbsorbPointer(
absorbing: !_active,
child: widget.child,
);
if (!_active) {
child = FocusScope(
canRequestFocus: false,
debugLabel: '$_TappableWhileStatusIs',
child: child,
);
}
return child;
}
}
class _FrontLayer extends StatelessWidget {
const _FrontLayer({
Key key,
@@ -275,12 +334,20 @@ class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin
return Stack(
key: _backdropKey,
children: <Widget>[
widget.backLayer,
_TappableWhileStatusIs(
AnimationStatus.dismissed,
controller: _controller,
child: widget.backLayer,
),
PositionedTransition(
rect: _layerAnimation,
child: _FrontLayer(
onTap: _toggleBackdropLayerVisibility,
child: widget.frontLayer,
child: _TappableWhileStatusIs(
AnimationStatus.completed,
controller: _controller,
child: widget.frontLayer,
),
),
),
],

View File

@@ -48,6 +48,8 @@ class TypographyDemo extends StatelessWidget {
Widget build(BuildContext context) {
final TextTheme textTheme = Theme.of(context).textTheme;
final List<Widget> styleItems = <Widget>[
if (MediaQuery.of(context).size.width > 500.0)
TextStyleItem(name: 'Display 4', style: textTheme.display4, text: 'Light 112sp'),
TextStyleItem(name: 'Display 3', style: textTheme.display3, text: 'Regular 56sp'),
TextStyleItem(name: 'Display 2', style: textTheme.display2, text: 'Regular 45sp'),
TextStyleItem(name: 'Display 1', style: textTheme.display1, text: 'Regular 34sp'),
@@ -60,14 +62,6 @@ class TypographyDemo extends StatelessWidget {
TextStyleItem(name: 'Button', style: textTheme.button, text: 'MEDIUM (ALL CAPS) 14sp'),
];
if (MediaQuery.of(context).size.width > 500.0) {
styleItems.insert(0, TextStyleItem(
name: 'Display 4',
style: textTheme.display4,
text: 'Light 112sp',
));
}
return Scaffold(
appBar: AppBar(title: const Text('Typography')),
body: SafeArea(

View File

@@ -66,10 +66,19 @@ class _TappableWhileStatusIsState extends State<_TappableWhileStatusIs> {
@override
Widget build(BuildContext context) {
return AbsorbPointer(
Widget child = AbsorbPointer(
absorbing: !_active,
child: widget.child,
);
if (!_active) {
child = FocusScope(
canRequestFocus: false,
debugLabel: '$_TappableWhileStatusIs',
child: child,
);
}
return child;
}
}
@@ -138,36 +147,31 @@ class _BackAppBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
final List<Widget> children = <Widget>[
Container(
alignment: Alignment.center,
width: 56.0,
child: leading,
),
Expanded(
child: title,
),
];
if (trailing != null) {
children.add(
Container(
alignment: Alignment.center,
width: 56.0,
child: trailing,
),
);
}
final ThemeData theme = Theme.of(context);
return IconTheme.merge(
data: theme.primaryIconTheme,
child: DefaultTextStyle(
style: theme.primaryTextTheme.title,
child: SizedBox(
height: _kBackAppBarHeight,
child: Row(children: children),
child: Row(
children: <Widget>[
Container(
alignment: Alignment.center,
width: 56.0,
child: leading,
),
Expanded(
child: title,
),
if (trailing != null)
Container(
alignment: Alignment.center,
width: 56.0,
child: trailing,
),
],
),
),
),
);
@@ -255,95 +259,92 @@ class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin
begin: RelativeRect.fromLTRB(0.0, constraints.biggest.height - _kFrontClosedHeight, 0.0, 0.0),
end: const RelativeRect.fromLTRB(0.0, _kBackAppBarHeight, 0.0, 0.0),
));
final List<Widget> layers = <Widget>[
// Back layer
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
_BackAppBar(
leading: widget.frontAction,
title: _CrossFadeTransition(
progress: _controller,
alignment: AlignmentDirectional.centerStart,
child0: Semantics(namesRoute: true, child: widget.frontTitle),
child1: Semantics(namesRoute: true, child: widget.backTitle),
),
trailing: IconButton(
onPressed: _toggleFrontLayer,
tooltip: 'Toggle options page',
icon: AnimatedIcon(
icon: AnimatedIcons.close_menu,
progress: _controller,
),
),
),
Expanded(
child: Visibility(
child: widget.backLayer,
visible: _controller.status != AnimationStatus.completed,
maintainState: true,
),
),
],
),
// Front layer
PositionedTransition(
rect: frontRelativeRect,
child: AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return PhysicalShape(
elevation: 12.0,
color: Theme.of(context).canvasColor,
clipper: ShapeBorderClipper(
shape: BeveledRectangleBorder(
borderRadius: _kFrontHeadingBevelRadius.transform(_controller.value),
),
),
clipBehavior: Clip.antiAlias,
child: child,
);
},
child: _TappableWhileStatusIs(
AnimationStatus.completed,
controller: _controller,
child: FadeTransition(
opacity: _frontOpacity,
child: widget.frontLayer,
),
),
),
),
];
// The front "heading" is a (typically transparent) widget that's stacked on
// top of, and at the top of, the front layer. It adds support for dragging
// the front layer up and down and for opening and closing the front layer
// with a tap. It may obscure part of the front layer's topmost child.
if (widget.frontHeading != null) {
layers.add(
PositionedTransition(
rect: frontRelativeRect,
child: ExcludeSemantics(
child: Container(
alignment: Alignment.topLeft,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: _toggleFrontLayer,
onVerticalDragUpdate: _handleDragUpdate,
onVerticalDragEnd: _handleDragEnd,
child: widget.frontHeading,
),
),
),
),
);
}
return Stack(
key: _backdropKey,
children: layers,
children: <Widget>[
// Back layer
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
_BackAppBar(
leading: widget.frontAction,
title: _CrossFadeTransition(
progress: _controller,
alignment: AlignmentDirectional.centerStart,
child0: Semantics(namesRoute: true, child: widget.frontTitle),
child1: Semantics(namesRoute: true, child: widget.backTitle),
),
trailing: IconButton(
onPressed: _toggleFrontLayer,
tooltip: 'Toggle options page',
icon: AnimatedIcon(
icon: AnimatedIcons.close_menu,
progress: _controller,
),
),
),
Expanded(
child: _TappableWhileStatusIs(
AnimationStatus.dismissed,
controller: _controller,
child: Visibility(
child: widget.backLayer,
visible: _controller.status != AnimationStatus.completed,
maintainState: true,
),
),
),
],
),
// Front layer
PositionedTransition(
rect: frontRelativeRect,
child: AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return PhysicalShape(
elevation: 12.0,
color: Theme.of(context).canvasColor,
clipper: ShapeBorderClipper(
shape: BeveledRectangleBorder(
borderRadius: _kFrontHeadingBevelRadius.transform(_controller.value),
),
),
clipBehavior: Clip.antiAlias,
child: child,
);
},
child: _TappableWhileStatusIs(
AnimationStatus.completed,
controller: _controller,
child: FadeTransition(
opacity: _frontOpacity,
child: widget.frontLayer,
),
),
),
),
// The front "heading" is a (typically transparent) widget that's stacked on
// top of, and at the top of, the front layer. It adds support for dragging
// the front layer up and down and for opening and closing the front layer
// with a tap. It may obscure part of the front layer's topmost child.
if (widget.frontHeading != null)
PositionedTransition(
rect: frontRelativeRect,
child: ExcludeSemantics(
child: Container(
alignment: Alignment.topLeft,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: _toggleFrontLayer,
onVerticalDragUpdate: _handleDragUpdate,
onVerticalDragEnd: _handleDragEnd,
child: widget.frontHeading,
),
),
),
),
],
);
}

View File

@@ -184,26 +184,6 @@ class _DemoItem extends StatelessWidget {
final ThemeData theme = Theme.of(context);
final bool isDark = theme.brightness == Brightness.dark;
final double textScaleFactor = MediaQuery.textScaleFactorOf(context);
final List<Widget> titleChildren = <Widget>[
Text(
demo.title,
style: theme.textTheme.subhead.copyWith(
color: isDark ? Colors.white : const Color(0xFF202124),
),
),
];
if (demo.subtitle != null) {
titleChildren.add(
Text(
demo.subtitle,
style: theme.textTheme.body1.copyWith(
color: isDark ? Colors.white : const Color(0xFF60646B)
),
),
);
}
return RawMaterialButton(
padding: EdgeInsets.zero,
splashColor: theme.primaryColor.withOpacity(0.12),
@@ -229,7 +209,21 @@ class _DemoItem extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: titleChildren,
children: <Widget>[
Text(
demo.title,
style: theme.textTheme.subhead.copyWith(
color: isDark ? Colors.white : const Color(0xFF202124),
),
),
if (demo.subtitle != null)
Text(
demo.subtitle,
style: theme.textTheme.body1.copyWith(
color: isDark ? Colors.white : const Color(0xFF60646B)
),
),
],
),
),
const SizedBox(width: 44.0),
@@ -294,11 +288,11 @@ class _GalleryHomeState extends State<GalleryHome> with SingleTickerProviderStat
GalleryDemoCategory _category;
static Widget _topHomeLayout(Widget currentChild, List<Widget> previousChildren) {
List<Widget> children = previousChildren;
if (currentChild != null)
children = children.toList()..add(currentChild);
return Stack(
children: children,
children: <Widget>[
...previousChildren,
if (currentChild != null) currentChild,
],
alignment: Alignment.topCenter,
);
}

View File

@@ -425,13 +425,10 @@ class GalleryOptionsPage extends StatelessWidget {
options.showPerformanceOverlay == null)
return const <Widget>[];
final List<Widget> items = <Widget>[
return <Widget>[
const Divider(),
const _Heading('Diagnostics'),
];
if (options.showOffscreenLayersCheckerboard != null) {
items.add(
if (options.showOffscreenLayersCheckerboard != null)
_BooleanItem(
'Highlight offscreen layers',
options.showOffscreenLayersCheckerboard,
@@ -439,10 +436,7 @@ class GalleryOptionsPage extends StatelessWidget {
onOptionsChanged(options.copyWith(showOffscreenLayersCheckerboard: value));
},
),
);
}
if (options.showRasterCacheImagesCheckerboard != null) {
items.add(
if (options.showRasterCacheImagesCheckerboard != null)
_BooleanItem(
'Highlight raster cache images',
options.showRasterCacheImagesCheckerboard,
@@ -450,10 +444,7 @@ class GalleryOptionsPage extends StatelessWidget {
onOptionsChanged(options.copyWith(showRasterCacheImagesCheckerboard: value));
},
),
);
}
if (options.showPerformanceOverlay != null) {
items.add(
if (options.showPerformanceOverlay != null)
_BooleanItem(
'Show performance overlay',
options.showPerformanceOverlay,
@@ -461,10 +452,7 @@ class GalleryOptionsPage extends StatelessWidget {
onOptionsChanged(options.copyWith(showPerformanceOverlay: value));
},
),
);
}
return items;
];
}
@override