defaultStyleOf method
Returns a ButtonStyle that's based primarily on the Theme's ThemeData.textTheme and ThemeData.colorScheme, but has most values filled out (non-null).
The returned style can be overridden by the style parameter and by the style returned by themeStyleOf that some button-specific themes like TextButtonTheme or ElevatedButtonTheme override. For example the default style of the TextButton subclass can be overridden with its TextButton.style constructor parameter, or with a TextButtonTheme.
Concrete button subclasses should return a ButtonStyle with as many non-null properties as possible, where all of the non-null WidgetStateProperty properties resolve to non-null values.
Properties that can be null
Some properties, like ButtonStyle.fixedSize would override other values in the same ButtonStyle if set, so they are allowed to be null. Here is a summary of properties that are allowed to be null when returned in the ButtonStyle returned by this function, an why:
- ButtonStyle.fixedSize because it would override other values in the same ButtonStyle, like ButtonStyle.maximumSize.
- ButtonStyle.side because null is a valid value for a button that has no side. OutlinedButton returns a non-null default for this, however.
- ButtonStyle.backgroundBuilder and ButtonStyle.foregroundBuilder because they would override the ButtonStyle.foregroundColor and ButtonStyle.backgroundColor of the same ButtonStyle.
See also:
- themeStyleOf, returns the ButtonStyle of this button's component theme.
Implementation
@override
material.ButtonStyle defaultStyleOf(widgets.BuildContext context) {
final face = context.face;
final metrics = _ButtonMetrics.fromSize(size, compact: compact);
final foreground = widgets.WidgetStateProperty.resolveWith<widgets.Color?>(
(states) => _resolveColors(context, states).foreground,
);
return material.ButtonStyle(
textStyle: widgets.WidgetStatePropertyAll(face.type(metrics.typeToken)),
backgroundColor: widgets.WidgetStateProperty.resolveWith<widgets.Color?>(
(states) => _resolveColors(context, states).background,
),
foregroundColor: foreground,
iconColor: foreground,
overlayColor: const widgets.WidgetStatePropertyAll(
widgets.Color(0x00000000),
),
shadowColor: const widgets.WidgetStatePropertyAll(
widgets.Color(0x00000000),
),
surfaceTintColor: const widgets.WidgetStatePropertyAll(
widgets.Color(0x00000000),
),
elevation: const widgets.WidgetStatePropertyAll(0),
padding: widgets.WidgetStatePropertyAll(
widgets.EdgeInsets.symmetric(
horizontal: face.space(metrics.horizontalSpace),
vertical: face.space(metrics.verticalSpace),
),
),
minimumSize: widgets.WidgetStatePropertyAll(
widgets.Size(0, face.rem(metrics.minHeight)),
),
maximumSize: const widgets.WidgetStatePropertyAll(widgets.Size.infinite),
iconSize: widgets.WidgetStatePropertyAll(face.rem(metrics.iconSize)),
// Актуальное место для настройки icon alignment.
//
// ButtonStyleButton.iconAlignment уже deprecated.
iconAlignment: iconPosition,
side: widgets.WidgetStateProperty.resolveWith<widgets.BorderSide?>((
states,
) {
final border = _resolveColors(context, states).border;
if (border == null) {
return widgets.BorderSide.none;
}
return widgets.BorderSide(color: border);
}),
shape: widgets.WidgetStatePropertyAll(
material.RoundedRectangleBorder(
borderRadius: widgets.BorderRadius.circular(face.radius('lg')),
),
),
mouseCursor: widgets.WidgetStateMouseCursor.adaptiveClickable,
// Carpenter сам управляет metrics.
visualDensity: material.VisualDensity.standard,
// Не добавляем Material minimum tap target поверх
// Carpenter размеров.
tapTargetSize: material.MaterialTapTargetSize.shrinkWrap,
animationDuration: face.motion.fast,
enableFeedback: true,
alignment: widgets.Alignment.center,
// Hover / focus / pressed уже выражаются Carpenter-цветами.
splashFactory: material.NoSplash.splashFactory,
);
}