Getting rid of containers (#147432)

This pull request aims to make the Flutter framework more efficient,
based on issue #147431.
This commit is contained in:
Nate 2024-05-09 16:31:54 -06:00 committed by GitHub
parent 77427f6608
commit 94a7151eb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 480 additions and 428 deletions

View File

@ -120,33 +120,26 @@ class _CupertinoContextMenuActionState extends State<CupertinoContextMenuAction>
),
child: Semantics(
button: true,
child: Container(
decoration: BoxDecoration(
color: _isPressed
child: ColoredBox(
color: _isPressed
? CupertinoDynamicColor.resolve(_kBackgroundColorPressed, context)
: CupertinoDynamicColor.resolve(_kBackgroundColor, context),
),
padding: const EdgeInsets.only(
top: 8,
bottom: 8,
left: 15.5,
right: 17.5,
),
child: DefaultTextStyle(
style: _textStyle,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
child: widget.child,
),
if (widget.trailingIcon != null)
Icon(
widget.trailingIcon,
color: _textStyle.color,
size: 21.0,
),
],
child: Padding(
padding: const EdgeInsets.fromLTRB(15.5, 8.0, 17.5, 8.0),
child: DefaultTextStyle(
style: _textStyle,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(child: widget.child),
if (widget.trailingIcon != null)
Icon(
widget.trailingIcon,
color: _textStyle.color,
size: 21.0,
),
],
),
),
),
),

View File

@ -1050,10 +1050,11 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> {
final List<Widget> pickers = <Widget>[];
double totalColumnWidths = 4 * _kDatePickerPadSize;
for (int i = 0; i < columnWidths.length; i++) {
for (final (int i, double width) in columnWidths.indexed) {
final (bool firstColumn, bool lastColumn) = (i == 0, i == columnWidths.length - 1);
double offAxisFraction = 0.0;
Widget selectionOverlay = _centerSelectionOverlay;
if (i == 0) {
if (firstColumn) {
offAxisFraction = -_kMaximumOffAxisFraction * textDirectionFactor;
selectionOverlay = _startSelectionOverlay;
} else if (i >= 2 || columnWidths.length == 2) {
@ -1061,7 +1062,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> {
}
EdgeInsets padding = const EdgeInsets.only(right: _kDatePickerPadSize);
if (i == columnWidths.length - 1) {
if (lastColumn) {
padding = padding.flipped;
selectionOverlay = _endSelectionOverlay;
}
@ -1069,24 +1070,23 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> {
padding = padding.flipped;
}
totalColumnWidths += columnWidths[i] + (2 * _kDatePickerPadSize);
totalColumnWidths += width + (2 * _kDatePickerPadSize);
pickers.add(LayoutId(
id: i,
child: pickerBuilders[i](
offAxisFraction,
(BuildContext context, Widget? child) {
return Container(
alignment: i == columnWidths.length - 1
? alignCenterLeft
: alignCenterRight,
late final Widget constrained = ConstrainedBox(
constraints: BoxConstraints(maxWidth: width + _kDatePickerPadSize),
child: child,
);
return Padding(
padding: padding,
child: Container(
alignment: i == columnWidths.length - 1 ? alignCenterLeft : alignCenterRight,
width: i == 0 || i == columnWidths.length - 1
? null
: columnWidths[i] + _kDatePickerPadSize,
child: child,
child: Align(
alignment: lastColumn ? alignCenterLeft : alignCenterRight,
child: firstColumn || lastColumn ? constrained : child,
),
);
},
@ -1453,7 +1453,8 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> {
final List<Widget> pickers = <Widget>[];
double totalColumnWidths = 4 * _kDatePickerPadSize;
for (int i = 0; i < columnWidths.length; i++) {
for (final (int i, double width) in columnWidths.indexed) {
final (bool firstColumn, bool lastColumn) = (i == 0, i == columnWidths.length - 1);
final double offAxisFraction = (i - 1) * 0.3 * textDirectionFactor;
EdgeInsets padding = const EdgeInsets.only(right: _kDatePickerPadSize);
@ -1462,28 +1463,30 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> {
}
Widget selectionOverlay = _centerSelectionOverlay;
if (i == 0) {
if (firstColumn) {
selectionOverlay = _startSelectionOverlay;
} else if (i == columnWidths.length - 1) {
selectionOverlay = _endSelectionOverlay;
}
totalColumnWidths += columnWidths[i] + (2 * _kDatePickerPadSize);
totalColumnWidths += width + (2 * _kDatePickerPadSize);
pickers.add(LayoutId(
id: i,
child: pickerBuilders[i](
offAxisFraction,
(BuildContext context, Widget? child) {
return Container(
alignment: i == columnWidths.length - 1
? alignCenterLeft
: alignCenterRight,
padding: i == 0 ? null : padding,
child: Container(
alignment: i == 0 ? alignCenterLeft : alignCenterRight,
width: columnWidths[i] + _kDatePickerPadSize,
child: child,
return Padding(
padding: firstColumn ? EdgeInsets.zero : padding,
child: Align(
alignment: lastColumn ? alignCenterLeft : alignCenterRight,
child: SizedBox(
width: width + _kDatePickerPadSize,
child: Align(
alignment: firstColumn ? alignCenterLeft : alignCenterRight,
child: child,
),
),
),
);
},
@ -1763,33 +1766,39 @@ class _CupertinoDatePickerMonthYearState extends State<CupertinoDatePicker> {
final List<Widget> pickers = <Widget>[];
double totalColumnWidths = 3 * _kDatePickerPadSize;
for (int i = 0; i < columnWidths.length; i++) {
final (bool first, bool last) = (i == 0, i == columnWidths.length - 1);
final double offAxisFraction = textDirectionFactor * (first ? -0.3 : 0.5);
for (final (int i, double width) in columnWidths.indexed) {
final (bool firstColumn, bool lastColumn) = (i == 0, i == columnWidths.length - 1);
final double offAxisFraction = textDirectionFactor * (firstColumn ? -0.3 : 0.5);
totalColumnWidths += columnWidths[i] + (2 * _kDatePickerPadSize);
totalColumnWidths += width + (2 * _kDatePickerPadSize);
pickers.add(LayoutId(
id: i,
child: pickerBuilders[i](
offAxisFraction,
(BuildContext context, Widget? child) {
return Container(
alignment: last ? alignCenterLeft : alignCenterRight,
padding: switch (textDirectionFactor) {
_ when first => null,
-1 => const EdgeInsets.only(left: _kDatePickerPadSize),
_ => const EdgeInsets.only(right: _kDatePickerPadSize),
},
child: Container(
alignment: first ? alignCenterLeft : alignCenterRight,
width: columnWidths[i] + _kDatePickerPadSize,
child: child,
final Widget contents = Align(
alignment: lastColumn ? alignCenterLeft : alignCenterRight,
child: SizedBox(
width: width + _kDatePickerPadSize,
child: Align(
alignment: firstColumn ? alignCenterLeft : alignCenterRight,
child: child,
),
),
);
if (firstColumn) {
return contents;
}
const EdgeInsets padding = EdgeInsets.only(right: _kDatePickerPadSize);
return Padding(
padding: textDirectionFactor == -1 ? padding.flipped : padding,
child: contents,
);
},
switch (last) {
_ when first => _startSelectionOverlay,
switch (lastColumn) {
_ when firstColumn => _startSelectionOverlay,
false => _centerSelectionOverlay,
true => _endSelectionOverlay,
},
@ -2127,22 +2136,24 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
);
return IgnorePointer(
child: Container(
alignment: AlignmentDirectional.centerStart.resolve(textDirection),
child: Padding(
padding: padding.resolve(textDirection),
child: SizedBox(
height: numberLabelHeight,
child: Baseline(
baseline: numberLabelBaseline,
baselineType: TextBaseline.alphabetic,
child: Text(
text,
style: const TextStyle(
fontSize: _kTimerPickerLabelFontSize,
fontWeight: FontWeight.w600,
child: Align(
alignment: AlignmentDirectional.centerStart.resolve(textDirection),
child: SizedBox(
height: numberLabelHeight,
child: Baseline(
baseline: numberLabelBaseline,
baselineType: TextBaseline.alphabetic,
child: Text(
text,
style: const TextStyle(
fontSize: _kTimerPickerLabelFontSize,
fontWeight: FontWeight.w600,
),
maxLines: 1,
softWrap: false,
),
maxLines: 1,
softWrap: false,
),
),
),
@ -2153,14 +2164,20 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
// The picker has to be wider than its content, since the separators
// are part of the picker.
Widget _buildPickerNumberLabel(String text, EdgeInsetsDirectional padding) {
return Container(
return SizedBox(
width: _kTimerPickerColumnIntrinsicWidth + padding.horizontal,
padding: padding.resolve(textDirection),
alignment: AlignmentDirectional.centerStart.resolve(textDirection),
child: Container(
width: numberLabelWidth,
alignment: AlignmentDirectional.centerEnd.resolve(textDirection),
child: Text(text, softWrap: false, maxLines: 1, overflow: TextOverflow.visible),
child: Padding(
padding: padding.resolve(textDirection),
child: Align(
alignment: AlignmentDirectional.centerStart.resolve(textDirection),
child: SizedBox(
width: numberLabelWidth,
child: Align(
alignment: AlignmentDirectional.centerEnd.resolve(textDirection),
child: Text(text, softWrap: false, maxLines: 1, overflow: TextOverflow.visible),
),
),
),
),
);
}
@ -2508,9 +2525,23 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
),
];
}
Widget contents = SizedBox(
width: totalWidth,
height: _kPickerHeight,
child: DefaultTextStyle(
style: _textStyleFrom(context),
child: Row(children: columns.map((Widget child) => Expanded(child: child)).toList(growable: false)),
),
);
final Color? color = CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context);
if (color != null) {
contents = ColoredBox(color: color, child: contents);
}
final CupertinoThemeData themeData = CupertinoTheme.of(context);
// The native iOS picker's text scaling is fixed, so we will also fix it
// as well in our picker.
// Text scaling is fixed to match the native iOS date picker.
return MediaQuery.withNoTextScaling(
child: CupertinoTheme(
data: themeData.copyWith(
@ -2518,18 +2549,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
pickerTextStyle: _textStyleFrom(context, _kTimerPickerMagnification),
),
),
child: Align(
alignment: widget.alignment,
child: Container(
color: CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context),
width: totalWidth,
height: _kPickerHeight,
child: DefaultTextStyle(
style: _textStyleFrom(context),
child: Row(children: columns.map((Widget child) => Expanded(child: child)).toList(growable: false)),
),
),
),
child: Align(alignment: widget.alignment, child: contents),
),
);
},

View File

@ -309,8 +309,9 @@ class _CupertinoAlertDialogState extends State<CupertinoAlertDialog> {
}
Widget _buildActions() {
Widget actionSection = Container(
height: 0.0,
Widget actionSection = const LimitedBox(
maxWidth: 0,
child: SizedBox(width: double.infinity, height: 0),
);
if (widget.actions.isNotEmpty) {
actionSection = _CupertinoAlertActionSection(
@ -348,22 +349,24 @@ class _CupertinoAlertDialogState extends State<CupertinoAlertDialog> {
removeBottom: true,
context: context,
child: Center(
child: Container(
margin: const EdgeInsets.symmetric(vertical: _kDialogEdgePadding),
width: isInAccessibilityMode
? _kAccessibilityCupertinoDialogWidth
: _kCupertinoDialogWidth,
child: CupertinoPopupSurface(
isSurfacePainted: false,
child: Semantics(
namesRoute: true,
scopesRoute: true,
explicitChildNodes: true,
label: localizations.alertDialogLabel,
child: _CupertinoDialogRenderWidget(
contentSection: _buildContent(context),
actionsSection: _buildActions(),
dividerColor: CupertinoColors.separator,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: _kDialogEdgePadding),
child: SizedBox(
width: isInAccessibilityMode
? _kAccessibilityCupertinoDialogWidth
: _kCupertinoDialogWidth,
child: CupertinoPopupSurface(
isSurfacePainted: false,
child: Semantics(
namesRoute: true,
scopesRoute: true,
explicitChildNodes: true,
label: localizations.alertDialogLabel,
child: _CupertinoDialogRenderWidget(
contentSection: _buildContent(context),
actionsSection: _buildActions(),
dividerColor: CupertinoColors.separator,
),
),
),
),
@ -424,14 +427,18 @@ class CupertinoPopupSurface extends StatelessWidget {
@override
Widget build(BuildContext context) {
Widget? contents = child;
if (isSurfacePainted) {
contents = ColoredBox(
color: CupertinoDynamicColor.resolve(_kDialogColor, context),
child: contents,
);
}
return ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(_kCornerRadius)),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: _kBlurAmount, sigmaY: _kBlurAmount),
child: Container(
color: isSurfacePainted ? CupertinoDynamicColor.resolve(_kDialogColor, context) : null,
child: child,
),
child: contents,
),
);
}
@ -596,8 +603,9 @@ class _CupertinoActionSheetState extends State<CupertinoActionSheet> {
Widget _buildActions() {
if (widget.actions == null || widget.actions!.isEmpty) {
return Container(
height: 0.0,
return const LimitedBox(
maxWidth: 0,
child: SizedBox(width: double.infinity, height: 0),
);
}
return _CupertinoAlertActionSection(
@ -655,16 +663,18 @@ class _CupertinoActionSheetState extends State<CupertinoActionSheet> {
label: 'Alert',
child: CupertinoUserInterfaceLevel(
data: CupertinoUserInterfaceLevelData.elevated,
child: Container(
width: actionSheetWidth - _kActionSheetEdgeHorizontalPadding * 2,
margin: const EdgeInsets.symmetric(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: _kActionSheetEdgeHorizontalPadding,
vertical: _kActionSheetEdgeVerticalPadding,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
child: SizedBox(
width: actionSheetWidth - _kActionSheetEdgeHorizontalPadding * 2,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
),
),
),
),
@ -731,8 +741,7 @@ class CupertinoActionSheetAction extends StatelessWidget {
),
child: Semantics(
button: true,
child: Container(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 10.0,
@ -740,7 +749,7 @@ class CupertinoActionSheetAction extends StatelessWidget {
child: DefaultTextStyle(
style: style,
textAlign: TextAlign.center,
child: child,
child: Center(child: child),
),
),
),
@ -1752,10 +1761,9 @@ class CupertinoDialogAction extends StatelessWidget {
constraints: const BoxConstraints(
minHeight: _kDialogMinButtonHeight,
),
child: Container(
alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.all(padding),
child: sizedContent,
child: Center(child: sizedContent),
),
),
),

View File

@ -558,7 +558,7 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo
widget.refreshIndicatorExtent,
);
}
return Container();
return const LimitedBox(maxWidth: 0.0, maxHeight: 0.0, child: SizedBox.expand());
},
),
);

View File

@ -590,8 +590,8 @@ class _PackagesViewState extends State<_PackagesView> {
child: Material(
color: Theme.of(context).cardColor,
elevation: 4.0,
child: Container(
constraints: BoxConstraints.loose(const Size.fromWidth(600.0)),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 600.0),
child: _packagesList(context, selectedId, snapshot.data!, widget.isLateral),
),
),
@ -887,8 +887,8 @@ class _PackageLicensePageState extends State<_PackageLicensePage> {
child: Material(
color: theme.cardColor,
elevation: 4.0,
child: Container(
constraints: BoxConstraints.loose(const Size.fromWidth(600.0)),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 600.0),
child: Localizations.override(
locale: const Locale('en', 'US'),
context: context,
@ -1361,17 +1361,19 @@ class _MasterDetailScaffoldState extends State<_MasterDetailScaffold>
preferredSize: const Size.fromHeight(kToolbarHeight),
child: Row(
children: <Widget>[
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: masterViewWidth),
SizedBox(
width: masterViewWidth,
child: IconTheme(
data: Theme.of(context).primaryIconTheme,
child: Container(
alignment: AlignmentDirectional.centerEnd,
child: Padding(
padding: const EdgeInsets.all(8),
child: OverflowBar(
spacing: 8,
overflowAlignment: OverflowBarAlignment.end,
children: widget.actionBuilder!(context, _ActionLevel.view),
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: OverflowBar(
spacing: 8,
overflowAlignment: OverflowBarAlignment.end,
children: widget.actionBuilder!(context, _ActionLevel.view),
),
),
),
),
@ -1405,9 +1407,8 @@ class _MasterDetailScaffoldState extends State<_MasterDetailScaffold>
child,
),
duration: const Duration(milliseconds: 500),
child: Container(
child: SizedBox.expand(
key: ValueKey<Object?>(value ?? widget.initialArguments),
constraints: const BoxConstraints.expand(),
child: _DetailView(
builder: widget.detailPageBuilder,
arguments: value ?? widget.initialArguments,

View File

@ -345,14 +345,18 @@ class _MaterialBannerState extends State<MaterialBanner> {
?? bannerTheme.leadingPadding
?? const EdgeInsetsDirectional.only(end: 16.0);
final Widget actionsBar = Container(
alignment: AlignmentDirectional.centerEnd,
final Widget actionsBar = ConstrainedBox(
constraints: const BoxConstraints(minHeight: 52.0),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: OverflowBar(
overflowAlignment: widget.overflowAlignment,
spacing: 8,
children: widget.actions,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: OverflowBar(
overflowAlignment: widget.overflowAlignment,
spacing: 8,
children: widget.actions,
),
),
),
);
@ -373,8 +377,8 @@ class _MaterialBannerState extends State<MaterialBanner> {
?? bannerTheme.contentTextStyle
?? defaults.contentTextStyle;
Widget materialBanner = Container(
margin: margin,
Widget materialBanner = Padding(
padding: margin,
child: Material(
elevation: elevation,
color: backgroundColor,

View File

@ -784,7 +784,7 @@ class _Label extends StatelessWidget {
text = Align(
alignment: Alignment.bottomCenter,
heightFactor: 1.0,
child: Container(child: text),
child: text,
);
if (item.label != null) {

View File

@ -391,7 +391,7 @@ class _RawMaterialButtonState extends State<RawMaterialButton> with MaterialStat
mouseCursor: effectiveMouseCursor,
child: IconTheme.merge(
data: IconThemeData(color: effectiveTextColor),
child: Container(
child: Padding(
padding: padding,
child: Center(
widthFactor: 1.0,

View File

@ -244,11 +244,12 @@ class ButtonBar extends StatelessWidget {
child: child,
);
case ButtonBarLayoutBehavior.constrained:
return Container(
padding: EdgeInsets.symmetric(horizontal: paddingUnit),
return ConstrainedBox(
constraints: const BoxConstraints(minHeight: 52.0),
alignment: Alignment.center,
child: child,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: paddingUnit),
child: Center(child: child),
),
);
}
}

View File

@ -393,52 +393,54 @@ class _DatePickerModeToggleButtonState extends State<_DatePickerModeToggleButton
final TextTheme textTheme = Theme.of(context).textTheme;
final Color controlColor = colorScheme.onSurface.withOpacity(0.60);
return Container(
padding: const EdgeInsetsDirectional.only(start: 16, end: 4),
return SizedBox(
height: _subHeaderHeight,
child: Row(
children: <Widget>[
Flexible(
child: Semantics(
label: MaterialLocalizations.of(context).selectYearSemanticsLabel,
excludeSemantics: true,
button: true,
container: true,
child: SizedBox(
height: _subHeaderHeight,
child: InkWell(
onTap: widget.onTitlePressed,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row(
children: <Widget>[
Flexible(
child: Text(
widget.title,
overflow: TextOverflow.ellipsis,
style: textTheme.titleSmall?.copyWith(
child: Padding(
padding: const EdgeInsetsDirectional.only(start: 16, end: 4),
child: Row(
children: <Widget>[
Flexible(
child: Semantics(
label: MaterialLocalizations.of(context).selectYearSemanticsLabel,
excludeSemantics: true,
button: true,
container: true,
child: SizedBox(
height: _subHeaderHeight,
child: InkWell(
onTap: widget.onTitlePressed,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row(
children: <Widget>[
Flexible(
child: Text(
widget.title,
overflow: TextOverflow.ellipsis,
style: textTheme.titleSmall?.copyWith(
color: controlColor,
),
),
),
RotationTransition(
turns: _controller,
child: Icon(
Icons.arrow_drop_down,
color: controlColor,
),
),
),
RotationTransition(
turns: _controller,
child: Icon(
Icons.arrow_drop_down,
color: controlColor,
),
),
],
],
),
),
),
),
),
),
),
if (widget.mode == DatePickerMode.day)
// Give space for the prev/next month buttons that are underneath this row
const SizedBox(width: _monthNavButtonsWidth),
],
if (widget.mode == DatePickerMode.day)
// Give space for the prev/next month buttons that are underneath this row
const SizedBox(width: _monthNavButtonsWidth),
],
),
),
);
}
@ -755,25 +757,27 @@ class _MonthPickerState extends State<_MonthPicker> {
return Semantics(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsetsDirectional.only(start: 16, end: 4),
SizedBox(
height: _subHeaderHeight,
child: Row(
children: <Widget>[
const Spacer(),
IconButton(
icon: const Icon(Icons.chevron_left),
color: controlColor,
tooltip: _isDisplayingFirstMonth ? null : _localizations.previousMonthTooltip,
onPressed: _isDisplayingFirstMonth ? null : _handlePreviousMonth,
),
IconButton(
icon: const Icon(Icons.chevron_right),
color: controlColor,
tooltip: _isDisplayingLastMonth ? null : _localizations.nextMonthTooltip,
onPressed: _isDisplayingLastMonth ? null : _handleNextMonth,
),
],
child: Padding(
padding: const EdgeInsetsDirectional.only(start: 16, end: 4),
child: Row(
children: <Widget>[
const Spacer(),
IconButton(
icon: const Icon(Icons.chevron_left),
color: controlColor,
tooltip: _isDisplayingFirstMonth ? null : _localizations.previousMonthTooltip,
onPressed: _isDisplayingFirstMonth ? null : _handlePreviousMonth,
),
IconButton(
icon: const Icon(Icons.chevron_right),
color: controlColor,
tooltip: _isDisplayingLastMonth ? null : _localizations.nextMonthTooltip,
onPressed: _isDisplayingLastMonth ? null : _handleNextMonth,
),
],
),
),
),
Expanded(
@ -954,7 +958,7 @@ class _DayPickerState extends State<_DayPicker> {
while (day < daysInMonth) {
day++;
if (day < 1) {
dayItems.add(Container());
dayItems.add(const SizedBox.shrink());
} else {
final DateTime dayToBuild = DateTime(year, month, day);
final bool isDisabled =
@ -1291,12 +1295,11 @@ class _YearPickerState extends State<YearPicker> {
decoration: decoration,
height: decorationHeight,
width: decorationWidth,
child: Center(
child: Semantics(
selected: isSelected,
button: true,
child: Text(year.toString(), style: itemStyle),
),
alignment: Alignment.center,
child: Semantics(
selected: isSelected,
button: true,
child: Text(year.toString(), style: itemStyle),
),
),
);

View File

@ -224,8 +224,8 @@ class Card extends StatelessWidget {
return Semantics(
container: semanticContainer,
child: Container(
margin: margin ?? cardTheme.margin ?? defaults.margin!,
child: Padding(
padding: margin ?? cardTheme.margin ?? defaults.margin!,
child: Material(
type: MaterialType.card,
color: color ?? cardTheme.color ?? defaults.color,

View File

@ -536,28 +536,32 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
final Color? headerForegroundColor = datePickerTheme.headerForegroundColor ?? defaults.headerForegroundColor;
headlineStyle = headlineStyle?.copyWith(color: headerForegroundColor);
final Widget actions = Container(
alignment: AlignmentDirectional.centerEnd,
final Widget actions = ConstrainedBox(
constraints: const BoxConstraints(minHeight: 52.0),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: OverflowBar(
spacing: 8,
children: <Widget>[
TextButton(
style: datePickerTheme.cancelButtonStyle ?? defaults.cancelButtonStyle,
onPressed: _handleCancel,
child: Text(widget.cancelText ?? (
useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: OverflowBar(
spacing: 8,
children: <Widget>[
TextButton(
style: datePickerTheme.cancelButtonStyle ?? defaults.cancelButtonStyle,
onPressed: _handleCancel,
child: Text(widget.cancelText ?? (
useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
)),
),
TextButton(
style: datePickerTheme.confirmButtonStyle ?? defaults.confirmButtonStyle,
onPressed: _handleOk,
child: Text(widget.confirmText ?? localizations.okButtonLabel),
),
],
),
TextButton(
style: datePickerTheme.confirmButtonStyle ?? defaults.confirmButtonStyle,
onPressed: _handleOk,
child: Text(widget.confirmText ?? localizations.okButtonLabel),
),
],
),
),
);
@ -578,30 +582,32 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
return Form(
key: _formKey,
autovalidateMode: _autovalidateMode.value,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: SizedBox(
height: orientation == Orientation.portrait ? _inputFormPortraitHeight : _inputFormLandscapeHeight,
child: Shortcuts(
shortcuts: _formShortcutMap,
child: Column(
children: <Widget>[
const Spacer(),
InputDatePickerFormField(
initialDate: _selectedDate.value,
firstDate: widget.firstDate,
lastDate: widget.lastDate,
onDateSubmitted: _handleDateChanged,
onDateSaved: _handleDateChanged,
selectableDayPredicate: widget.selectableDayPredicate,
errorFormatText: widget.errorFormatText,
errorInvalidText: widget.errorInvalidText,
fieldHintText: widget.fieldHintText,
fieldLabelText: widget.fieldLabelText,
keyboardType: widget.keyboardType,
autofocus: true,
),
const Spacer(),
],
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Shortcuts(
shortcuts: _formShortcutMap,
child: Column(
children: <Widget>[
const Spacer(),
InputDatePickerFormField(
initialDate: _selectedDate.value,
firstDate: widget.firstDate,
lastDate: widget.lastDate,
onDateSubmitted: _handleDateChanged,
onDateSaved: _handleDateChanged,
selectableDayPredicate: widget.selectableDayPredicate,
errorFormatText: widget.errorFormatText,
errorInvalidText: widget.errorInvalidText,
fieldHintText: widget.fieldHintText,
fieldLabelText: widget.fieldLabelText,
keyboardType: widget.keyboardType,
autofocus: true,
),
const Spacer(),
],
),
),
),
),
@ -1508,36 +1514,38 @@ class _DateRangePickerDialogState extends State<DateRangePickerDialog> with Rest
selectedStartDate: _selectedStart.value,
selectedEndDate: _selectedEnd.value,
currentDate: widget.currentDate,
picker: Container(
padding: const EdgeInsets.symmetric(horizontal: 24),
picker: SizedBox(
height: orientation == Orientation.portrait
? _inputFormPortraitHeight
: _inputFormLandscapeHeight,
child: Column(
children: <Widget>[
const Spacer(),
_InputDateRangePicker(
key: _inputPickerKey,
initialStartDate: _selectedStart.value,
initialEndDate: _selectedEnd.value,
firstDate: widget.firstDate,
lastDate: widget.lastDate,
onStartDateChanged: _handleStartDateChanged,
onEndDateChanged: _handleEndDateChanged,
autofocus: true,
autovalidate: _autoValidate.value,
helpText: widget.helpText,
errorInvalidRangeText: widget.errorInvalidRangeText,
errorFormatText: widget.errorFormatText,
errorInvalidText: widget.errorInvalidText,
fieldStartHintText: widget.fieldStartHintText,
fieldEndHintText: widget.fieldEndHintText,
fieldStartLabelText: widget.fieldStartLabelText,
fieldEndLabelText: widget.fieldEndLabelText,
keyboardType: widget.keyboardType,
),
const Spacer(),
],
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Column(
children: <Widget>[
const Spacer(),
_InputDateRangePicker(
key: _inputPickerKey,
initialStartDate: _selectedStart.value,
initialEndDate: _selectedEnd.value,
firstDate: widget.firstDate,
lastDate: widget.lastDate,
onStartDateChanged: _handleStartDateChanged,
onEndDateChanged: _handleEndDateChanged,
autofocus: true,
autovalidate: _autoValidate.value,
helpText: widget.helpText,
errorInvalidRangeText: widget.errorInvalidRangeText,
errorFormatText: widget.errorFormatText,
errorInvalidText: widget.errorInvalidText,
fieldStartHintText: widget.fieldStartHintText,
fieldEndHintText: widget.fieldEndHintText,
fieldStartLabelText: widget.fieldStartLabelText,
fieldEndLabelText: widget.fieldEndLabelText,
keyboardType: widget.keyboardType,
),
const Spacer(),
],
),
),
),
onConfirm: _handleOk,
@ -2157,11 +2165,11 @@ class _DayHeaders extends StatelessWidget {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final List<Widget> labels = _getDayHeaders(textStyle, localizations);
// Add leading and trailing containers for edges of the custom grid layout.
labels.insert(0, Container());
labels.add(Container());
// Add leading and trailing boxes for edges of the custom grid layout.
labels.insert(0, const SizedBox.shrink());
labels.add(const SizedBox.shrink());
return Container(
return ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.orientationOf(context) == Orientation.landscape
? _maxCalendarWidthLandscape
@ -2428,8 +2436,9 @@ class _MonthItemState extends State<_MonthItem> {
);
}
Widget _buildEdgeContainer(BuildContext context, bool isHighlighted) {
return Container(color: isHighlighted ? _highlightColor(context) : null);
Widget _buildEdgeBox(BuildContext context, bool isHighlighted) {
const Widget empty = LimitedBox(maxWidth: 0.0, maxHeight: 0.0, child: SizedBox.expand());
return isHighlighted ? ColoredBox(color: _highlightColor(context), child: empty) : empty;
}
@override
@ -2449,7 +2458,7 @@ class _MonthItemState extends State<_MonthItem> {
// a leap year.
for (int day = 0 - dayOffset + 1; day <= daysInMonth; day += 1) {
if (day < 1) {
dayItems.add(Container());
dayItems.add(const LimitedBox(maxWidth: 0.0, maxHeight: 0.0, child: SizedBox.expand()));
} else {
final DateTime dayToBuild = DateTime(year, month, day);
final Widget dayItem = _buildDayItem(
@ -2482,7 +2491,7 @@ class _MonthItemState extends State<_MonthItem> {
widget.selectedDateEnd != null &&
dateAfterLeadingPadding.isAfter(widget.selectedDateStart!) &&
!dateAfterLeadingPadding.isAfter(widget.selectedDateEnd!);
weekList.insert(0, _buildEdgeContainer(context, isLeadingInRange));
weekList.insert(0, _buildEdgeBox(context, isLeadingInRange));
// Only add a trailing edge container if it is for a full week and not a
// partial week.
@ -2496,7 +2505,7 @@ class _MonthItemState extends State<_MonthItem> {
widget.selectedDateEnd != null &&
!dateBeforeTrailingPadding.isBefore(widget.selectedDateStart!) &&
dateBeforeTrailingPadding.isBefore(widget.selectedDateEnd!);
weekList.add(_buildEdgeContainer(context, isTrailingInRange));
weekList.add(_buildEdgeBox(context, isTrailingInRange));
}
paddedDayItems.addAll(weekList);
@ -2507,19 +2516,22 @@ class _MonthItemState extends State<_MonthItem> {
: _maxCalendarWidthPortrait;
return Column(
children: <Widget>[
Container(
constraints: BoxConstraints(maxWidth: maxWidth),
height: _monthItemHeaderHeight,
padding: const EdgeInsets.symmetric(horizontal: 16),
alignment: AlignmentDirectional.centerStart,
child: ExcludeSemantics(
child: Text(
localizations.formatMonthYear(widget.displayedMonth),
style: textTheme.bodyMedium!.apply(color: themeData.colorScheme.onSurface),
ConstrainedBox(
constraints: BoxConstraints(maxWidth: maxWidth).tighten(height: _monthItemHeaderHeight),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Align(
alignment: AlignmentDirectional.centerStart,
child: ExcludeSemantics(
child: Text(
localizations.formatMonthYear(widget.displayedMonth),
style: textTheme.bodyMedium!.apply(color: themeData.colorScheme.onSurface),
),
),
),
),
),
Container(
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: maxWidth,
maxHeight: gridHeight,
@ -2693,13 +2705,12 @@ class _DayItemState extends State<_DayItem> {
Widget dayWidget = Container(
decoration: decoration,
child: Center(
child: Semantics(
label: semanticLabel,
selected: widget.isSelectedDayStart || widget.isSelectedDayEnd,
child: ExcludeSemantics(
child: Text(dayText, style: itemStyle),
),
alignment: Alignment.center,
child: Semantics(
label: semanticLabel,
selected: widget.isSelectedDayStart || widget.isSelectedDayEnd,
child: ExcludeSemantics(
child: Text(dayText, style: itemStyle),
),
),
);
@ -2868,26 +2879,30 @@ class _InputDateRangePickerDialog extends StatelessWidget {
entryModeButton: entryModeButton,
);
final Widget actions = Container(
alignment: AlignmentDirectional.centerEnd,
final Widget actions = ConstrainedBox(
constraints: const BoxConstraints(minHeight: 52.0),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: OverflowBar(
spacing: 8,
children: <Widget>[
TextButton(
onPressed: onCancel,
child: Text(cancelText ?? (
useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Align(
alignment: AlignmentDirectional.centerEnd,
child: OverflowBar(
spacing: 8,
children: <Widget>[
TextButton(
onPressed: onCancel,
child: Text(cancelText ?? (
useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
)),
),
TextButton(
onPressed: onConfirm,
child: Text(confirmText ?? localizations.okButtonLabel),
),
],
),
TextButton(
onPressed: onConfirm,
child: Text(confirmText ?? localizations.okButtonLabel),
),
],
),
),
);

View File

@ -682,7 +682,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
behavior: HitTestBehavior.translucent,
excludeFromSemantics: true,
dragStartBehavior: widget.dragStartBehavior,
child: Container(width: dragAreaWidth),
child: LimitedBox(maxHeight: 0.0, child: SizedBox(width: dragAreaWidth, height: double.infinity)),
),
);
} else {
@ -701,6 +701,11 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
platformHasBackButton = false;
}
Widget drawerScrim = const LimitedBox(maxWidth: 0.0, maxHeight: 0.0, child: SizedBox.expand());
if (_scrimColorTween.evaluate(_controller) case final Color color) {
drawerScrim = ColoredBox(color: color, child: drawerScrim);
}
final Widget child = _DrawerControllerScope(
controller: widget,
child: RepaintBoundary(
@ -714,9 +719,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
onTap: close,
child: Semantics(
label: MaterialLocalizations.of(context).modalBarrierDismissLabel,
child: Container( // The drawer's "scrim"
color: _scrimColorTween.evaluate(_controller),
),
child: drawerScrim,
),
),
),

View File

@ -200,11 +200,11 @@ class _DropdownMenuItemButtonState<T> extends State<_DropdownMenuItemButton<T>>
Widget build(BuildContext context) {
final DropdownMenuItem<T> dropdownMenuItem =
widget.route.items[widget.itemIndex].item!;
Widget child = Container(
padding: widget.padding,
height: widget.route.itemHeight,
child: widget.route.items[widget.itemIndex],
);
Widget child = widget.route.items[widget.itemIndex];
if (widget.padding case final EdgeInsetsGeometry padding) {
child = Padding(padding: padding, child: child);
}
child = SizedBox(height: widget.route.itemHeight, child: child);
// An [InkWell] is added to the item only if it is enabled
if (dropdownMenuItem.enabled) {
child = InkWell(
@ -775,10 +775,9 @@ class _DropdownMenuItemContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
return ConstrainedBox(
constraints: const BoxConstraints(minHeight: _kMenuItemHeight),
alignment: alignment,
child: child,
child: Align(alignment: alignment, child: child),
);
}
}
@ -1500,25 +1499,27 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
Widget result = DefaultTextStyle(
style: _enabled ? _textStyle! : _textStyle!.copyWith(color: Theme.of(context).disabledColor),
child: Container(
padding: padding.resolve(Directionality.of(context)),
child: SizedBox(
height: widget.isDense ? _denseButtonHeight : null,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (widget.isExpanded)
Expanded(child: innerItemsWidget)
else
innerItemsWidget,
IconTheme(
data: IconThemeData(
color: _iconColor,
size: widget.iconSize,
child: Padding(
padding: padding.resolve(Directionality.of(context)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (widget.isExpanded)
Expanded(child: innerItemsWidget)
else
innerItemsWidget,
IconTheme(
data: IconThemeData(
color: _iconColor,
size: widget.iconSize,
),
child: widget.icon ?? defaultIcon,
),
child: widget.icon ?? defaultIcon,
),
],
],
),
),
),
);

View File

@ -789,7 +789,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
hintText: widget.hintText,
helperText: widget.helperText,
errorText: widget.errorText,
prefixIcon: widget.leadingIcon != null ? Container(
prefixIcon: widget.leadingIcon != null ? SizedBox(
key: _leadingKey,
child: widget.leadingIcon
) : null,
@ -816,11 +816,13 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
},
);
if (widget.expandedInsets != null) {
menuAnchor = Container(
alignment: AlignmentDirectional.topStart,
padding: widget.expandedInsets?.copyWith(top: 0.0, bottom: 0.0),
child: menuAnchor,
if (widget.expandedInsets case final EdgeInsets padding) {
menuAnchor = Padding(
padding: padding.copyWith(top: 0.0, bottom: 0.0),
child: Align(
alignment: AlignmentDirectional.topStart,
child: menuAnchor,
),
);
}

View File

@ -99,10 +99,12 @@ void main() {
);
}
Finder findStaticChildDecoration(WidgetTester tester) {
Finder findStaticChildColor(WidgetTester tester) {
return find.descendant(
of: findStatic(),
matching: find.byType(DecoratedBox),
matching: find.byWidgetPredicate(
(Widget widget) => widget is ColoredBox && widget.color != CupertinoColors.activeOrange,
),
);
}
@ -496,7 +498,7 @@ void main() {
await tester.pumpAndSettle();
expect(findStatic(), findsOneWidget);
expect(findStaticChildDecoration(tester), findsNWidgets(1));
expect(findStaticChildColor(tester), findsNWidgets(1));
// Close the CupertinoContextMenu.
await tester.tapAt(const Offset(1.0, 1.0));
@ -528,7 +530,7 @@ void main() {
await tester.pumpAndSettle();
expect(findStatic(), findsOneWidget);
expect(findStaticChildDecoration(tester), findsNWidgets(3));
expect(findStaticChildColor(tester), findsNWidgets(2));
});
testWidgets('Can close CupertinoContextMenu by background tap', (WidgetTester tester) async {

View File

@ -18,12 +18,12 @@ void main() {
),
));
final Container container = _getCardContainer(tester);
final Padding padding = _getCardPadding(tester);
final Material material = _getCardMaterial(tester);
expect(material.clipBehavior, Clip.none);
expect(material.elevation, 1.0);
expect(container.margin, const EdgeInsets.all(4.0));
expect(padding.padding, const EdgeInsets.all(4.0));
expect(material.color, colors.surfaceContainerLow);
expect(material.shadowColor, colors.shadow);
expect(material.surfaceTintColor, Colors.transparent); // Don't use surface tint. Toned surface container is used instead.
@ -42,12 +42,12 @@ void main() {
),
));
final Container container = _getCardContainer(tester);
final Padding padding = _getCardPadding(tester);
final Material material = _getCardMaterial(tester);
expect(material.clipBehavior, Clip.none);
expect(material.elevation, 0.0);
expect(container.margin, const EdgeInsets.all(4.0));
expect(padding.padding, const EdgeInsets.all(4.0));
expect(material.color, colors.surfaceContainerHighest);
expect(material.shadowColor, colors.shadow);
expect(material.surfaceTintColor, Colors.transparent);
@ -66,12 +66,12 @@ void main() {
),
));
final Container container = _getCardContainer(tester);
final Padding padding = _getCardPadding(tester);
final Material material = _getCardMaterial(tester);
expect(material.clipBehavior, Clip.none);
expect(material.elevation, 0.0);
expect(container.margin, const EdgeInsets.all(4.0));
expect(padding.padding, const EdgeInsets.all(4.0));
expect(material.color, colors.surface);
expect(material.shadowColor, colors.shadow);
expect(material.surfaceTintColor, Colors.transparent);
@ -301,11 +301,11 @@ Material _getCardMaterial(WidgetTester tester) {
);
}
Container _getCardContainer(WidgetTester tester) {
return tester.widget<Container>(
Padding _getCardPadding(WidgetTester tester) {
return tester.widget<Padding>(
find.descendant(
of: find.byType(Card),
matching: find.byType(Container),
matching: find.byType(Padding),
),
);
}

View File

@ -31,7 +31,7 @@ void main() {
),
));
final Container container = _getCardContainer(tester);
final Padding padding = _getCardPadding(tester);
final Material material = _getCardMaterial(tester);
expect(material.clipBehavior, Clip.none);
@ -39,7 +39,7 @@ void main() {
expect(material.shadowColor, theme.colorScheme.shadow);
expect(material.surfaceTintColor, Colors.transparent); // Default primary color
expect(material.elevation, 1.0);
expect(container.margin, const EdgeInsets.all(4.0));
expect(padding.padding, const EdgeInsets.all(4.0));
expect(material.shape, const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
));
@ -55,7 +55,7 @@ void main() {
),
));
final Container container = _getCardContainer(tester);
final Padding padding = _getCardPadding(tester);
final Material material = _getCardMaterial(tester);
expect(material.clipBehavior, cardTheme.clipBehavior);
@ -63,7 +63,7 @@ void main() {
expect(material.shadowColor, cardTheme.shadowColor);
expect(material.surfaceTintColor, cardTheme.surfaceTintColor);
expect(material.elevation, cardTheme.elevation);
expect(container.margin, cardTheme.margin);
expect(padding.padding, cardTheme.margin);
expect(material.shape, cardTheme.shape);
});
@ -91,14 +91,14 @@ void main() {
),
));
final Container container = _getCardContainer(tester);
final Padding padding = _getCardPadding(tester);
final Material material = _getCardMaterial(tester);
expect(material.clipBehavior, clip);
expect(material.color, color);
expect(material.shadowColor, shadowColor);
expect(material.elevation, elevation);
expect(container.margin, margin);
expect(padding.padding, margin);
expect(material.shape, shape);
});
@ -187,7 +187,7 @@ void main() {
),
));
final Container container = _getCardContainer(tester);
final Padding padding = _getCardPadding(tester);
final Material material = _getCardMaterial(tester);
expect(material.clipBehavior, Clip.none);
@ -195,7 +195,7 @@ void main() {
expect(material.shadowColor, Colors.black);
expect(material.surfaceTintColor, null);
expect(material.elevation, 1.0);
expect(container.margin, const EdgeInsets.all(4.0));
expect(padding.padding, const EdgeInsets.all(4.0));
expect(material.shape, const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0)),
));
@ -261,11 +261,11 @@ Material _getCardMaterial(WidgetTester tester) {
);
}
Container _getCardContainer(WidgetTester tester) {
return tester.widget<Container>(
Padding _getCardPadding(WidgetTester tester) {
return tester.widget<Padding>(
find.descendant(
of: find.byType(Card),
matching: find.byType(Container),
matching: find.byType(Padding),
),
);
}

View File

@ -154,21 +154,18 @@ void main() {
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('Scaffold drawerScrimColor', (WidgetTester tester) async {
// The scrim is a Container within a Semantics node labeled "Dismiss",
// The scrim is a ColoredBox within a Semantics node labeled "Dismiss",
// within a DrawerController. Sorry.
Container getScrim() {
return tester.widget<Container>(
Widget getScrim() {
return tester.widget<Semantics>(
find.descendant(
of: find.descendant(
of: find.byType(DrawerController),
matching: find.byWidgetPredicate((Widget widget) {
return widget is Semantics
&& widget.properties.label == 'Dismiss';
}),
),
matching: find.byType(Container),
of: find.byType(DrawerController),
matching: find.byWidgetPredicate((Widget widget) {
return widget is Semantics
&& widget.properties.label == 'Dismiss';
}),
),
);
).child!;
}
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@ -196,7 +193,8 @@ void main() {
scaffoldKey.currentState!.openDrawer();
await tester.pumpAndSettle();
expect(getScrim().color, Colors.black54);
ColoredBox scrim = getScrim() as ColoredBox;
expect(scrim.color, Colors.black54);
await tester.tap(find.byType(Drawer));
await tester.pumpAndSettle();
@ -208,7 +206,8 @@ void main() {
scaffoldKey.currentState!.openDrawer();
await tester.pumpAndSettle();
expect(getScrim().color, const Color(0xFF323232));
scrim = getScrim() as ColoredBox;
expect(scrim.color, const Color(0xFF323232));
await tester.tap(find.byType(Drawer));
await tester.pumpAndSettle();

View File

@ -312,8 +312,8 @@ Material _drawerMaterial(WidgetTester tester) {
// The scrim is a Container within a Semantics node labeled "Dismiss",
// within a DrawerController.
Container _scrim(WidgetTester tester) {
return tester.widget<Container>(
ColoredBox _scrim(WidgetTester tester) {
return tester.widget<ColoredBox>(
find.descendant(
of: find.descendant(
of: find.byType(DrawerController),
@ -322,7 +322,7 @@ Container _scrim(WidgetTester tester) {
&& widget.properties.label == 'Dismiss';
}),
),
matching: find.byType(Container),
matching: find.byType(ColoredBox),
),
);
}

View File

@ -442,7 +442,7 @@ void main() {
label: const Text('label'),
));
final Finder leadingIcon = find.widgetWithIcon(Container, Icons.search);
final Finder leadingIcon = find.widgetWithIcon(SizedBox, Icons.search).last;
final double iconWidth = tester.getSize(leadingIcon).width;
final Finder updatedLabel = find.text('label');
final Offset updatedLabelTopLeft = tester.getTopLeft(updatedLabel);
@ -465,7 +465,7 @@ void main() {
label: const Text('label'),
));
final Finder largeLeadingIcon = find.widgetWithIcon(Container, Icons.search);
final Finder largeLeadingIcon = find.widgetWithIcon(SizedBox, Icons.search).last;
final double largeIconWidth = tester.getSize(largeLeadingIcon).width;
final Finder updatedLabel1 = find.text('label');
final Offset updatedLabelTopLeft1 = tester.getTopLeft(updatedLabel1);
@ -524,7 +524,7 @@ void main() {
));
await tester.pump();
final Finder leadingIcon = find.widgetWithIcon(Container, Icons.search);
final Finder leadingIcon = find.widgetWithIcon(SizedBox, Icons.search).last;
final double iconWidth = tester.getSize(leadingIcon).width;
final Offset dropdownMenuTopRight = tester.getTopRight(find.byType(DropdownMenu<TestMenu>));
final Finder updatedLabel = find.text('label');
@ -556,7 +556,7 @@ void main() {
));
await tester.pump();
final Finder largeLeadingIcon = find.widgetWithIcon(Container, Icons.search);
final Finder largeLeadingIcon = find.widgetWithIcon(SizedBox, Icons.search).last;
final double largeIconWidth = tester.getSize(largeLeadingIcon).width;
final Offset updatedDropdownMenuTopRight = tester.getTopRight(find.byType(DropdownMenu<TestMenu>));
final Finder updatedLabel1 = find.text('label');