Updated IconButton.iconSize to get value from theme (#87643)
This commit is contained in:
parent
c7572150fa
commit
2719f65bd3
@ -116,7 +116,7 @@ class IconButton extends StatelessWidget {
|
|||||||
/// or an [ImageIcon].
|
/// or an [ImageIcon].
|
||||||
const IconButton({
|
const IconButton({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.iconSize = 24.0,
|
this.iconSize,
|
||||||
this.visualDensity,
|
this.visualDensity,
|
||||||
this.padding = const EdgeInsets.all(8.0),
|
this.padding = const EdgeInsets.all(8.0),
|
||||||
this.alignment = Alignment.center,
|
this.alignment = Alignment.center,
|
||||||
@ -135,8 +135,7 @@ class IconButton extends StatelessWidget {
|
|||||||
this.enableFeedback = true,
|
this.enableFeedback = true,
|
||||||
this.constraints,
|
this.constraints,
|
||||||
required this.icon,
|
required this.icon,
|
||||||
}) : assert(iconSize != null),
|
}) : assert(padding != null),
|
||||||
assert(padding != null),
|
|
||||||
assert(alignment != null),
|
assert(alignment != null),
|
||||||
assert(splashRadius == null || splashRadius > 0),
|
assert(splashRadius == null || splashRadius > 0),
|
||||||
assert(autofocus != null),
|
assert(autofocus != null),
|
||||||
@ -145,7 +144,8 @@ class IconButton extends StatelessWidget {
|
|||||||
|
|
||||||
/// The size of the icon inside the button.
|
/// The size of the icon inside the button.
|
||||||
///
|
///
|
||||||
/// This property must not be null. It defaults to 24.0.
|
/// If null, uses [IconThemeData.size]. If it is also null, the default size
|
||||||
|
/// is 24.0.
|
||||||
///
|
///
|
||||||
/// The size given here is passed down to the widget in the [icon] property
|
/// The size given here is passed down to the widget in the [icon] property
|
||||||
/// via an [IconTheme]. Setting the size here instead of in, for example, the
|
/// via an [IconTheme]. Setting the size here instead of in, for example, the
|
||||||
@ -153,7 +153,7 @@ class IconButton extends StatelessWidget {
|
|||||||
/// fit the [Icon]. If you were to set the size of the [Icon] using
|
/// fit the [Icon]. If you were to set the size of the [Icon] using
|
||||||
/// [Icon.size] instead, then the [IconButton] would default to 24.0 and then
|
/// [Icon.size] instead, then the [IconButton] would default to 24.0 and then
|
||||||
/// the [Icon] itself would likely get clipped.
|
/// the [Icon] itself would likely get clipped.
|
||||||
final double iconSize;
|
final double? iconSize;
|
||||||
|
|
||||||
/// Defines how compact the icon button's layout will be.
|
/// Defines how compact the icon button's layout will be.
|
||||||
///
|
///
|
||||||
@ -319,19 +319,20 @@ class IconButton extends StatelessWidget {
|
|||||||
minHeight: _kMinButtonSize,
|
minHeight: _kMinButtonSize,
|
||||||
);
|
);
|
||||||
final BoxConstraints adjustedConstraints = effectiveVisualDensity.effectiveConstraints(unadjustedConstraints);
|
final BoxConstraints adjustedConstraints = effectiveVisualDensity.effectiveConstraints(unadjustedConstraints);
|
||||||
|
final double effectiveIconSize = iconSize ?? IconTheme.of(context).size ?? 24.0;
|
||||||
|
|
||||||
Widget result = ConstrainedBox(
|
Widget result = ConstrainedBox(
|
||||||
constraints: adjustedConstraints,
|
constraints: adjustedConstraints,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: padding,
|
padding: padding,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: iconSize,
|
height: effectiveIconSize,
|
||||||
width: iconSize,
|
width: effectiveIconSize,
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: alignment,
|
alignment: alignment,
|
||||||
child: IconTheme.merge(
|
child: IconTheme.merge(
|
||||||
data: IconThemeData(
|
data: IconThemeData(
|
||||||
size: iconSize,
|
size: effectiveIconSize,
|
||||||
color: currentColor,
|
color: currentColor,
|
||||||
),
|
),
|
||||||
child: icon,
|
child: icon,
|
||||||
@ -364,7 +365,7 @@ class IconButton extends StatelessWidget {
|
|||||||
splashColor: splashColor ?? theme.splashColor,
|
splashColor: splashColor ?? theme.splashColor,
|
||||||
radius: splashRadius ?? math.max(
|
radius: splashRadius ?? math.max(
|
||||||
Material.defaultSplashRadius,
|
Material.defaultSplashRadius,
|
||||||
(iconSize + math.min(padding.horizontal, padding.vertical)) * 0.7,
|
(effectiveIconSize + math.min(padding.horizontal, padding.vertical)) * 0.7,
|
||||||
// x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
|
// x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
|
||||||
),
|
),
|
||||||
child: result,
|
child: result,
|
||||||
|
@ -75,6 +75,119 @@ void main() {
|
|||||||
expect(iconButton.size, const Size(70.0, 70.0));
|
expect(iconButton.size, const Size(70.0, 70.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('when both iconSize and IconTheme.of(context).size are null, size falls back to 24.0', (WidgetTester tester) async {
|
||||||
|
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
|
||||||
|
await tester.pumpWidget(
|
||||||
|
wrap(
|
||||||
|
child: IconTheme(
|
||||||
|
data: const IconThemeData(size: null),
|
||||||
|
child: IconButton(
|
||||||
|
focusNode: focusNode,
|
||||||
|
onPressed: mockOnPressedFunction.handler,
|
||||||
|
icon: const Icon(Icons.link),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final RenderBox icon = tester.renderObject(find.byType(Icon));
|
||||||
|
expect(icon.size, const Size(24.0, 24.0));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('when null, iconSize is overridden by closest IconTheme', (WidgetTester tester) async {
|
||||||
|
RenderBox icon;
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
wrap(
|
||||||
|
child: IconTheme(
|
||||||
|
data: const IconThemeData(size: 10),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: mockOnPressedFunction.handler,
|
||||||
|
icon: const Icon(Icons.link),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
icon = tester.renderObject(find.byType(Icon));
|
||||||
|
expect(icon.size, const Size(10.0, 10.0));
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
wrap(
|
||||||
|
child: Theme(
|
||||||
|
data: ThemeData(
|
||||||
|
iconTheme: const IconThemeData(size: 10),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: mockOnPressedFunction.handler,
|
||||||
|
icon: const Icon(Icons.link),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
icon = tester.renderObject(find.byType(Icon));
|
||||||
|
expect(icon.size, const Size(10.0, 10.0));
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
wrap(
|
||||||
|
child: Theme(
|
||||||
|
data: ThemeData(
|
||||||
|
iconTheme: const IconThemeData(size: 20),
|
||||||
|
),
|
||||||
|
child: IconTheme(
|
||||||
|
data: const IconThemeData(size: 10),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: mockOnPressedFunction.handler,
|
||||||
|
icon: const Icon(Icons.link),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
icon = tester.renderObject(find.byType(Icon));
|
||||||
|
expect(icon.size, const Size(10.0, 10.0));
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
wrap(
|
||||||
|
child: IconTheme(
|
||||||
|
data: const IconThemeData(size: 20),
|
||||||
|
child: Theme(
|
||||||
|
data: ThemeData(
|
||||||
|
iconTheme: const IconThemeData(size: 10),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: mockOnPressedFunction.handler,
|
||||||
|
icon: const Icon(Icons.link),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
icon = tester.renderObject(find.byType(Icon));
|
||||||
|
expect(icon.size, const Size(10.0, 10.0));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('when non-null, iconSize precedes IconTheme.of(context).size', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
wrap(
|
||||||
|
child: IconTheme(
|
||||||
|
data: const IconThemeData(size: 30.0),
|
||||||
|
child: IconButton(
|
||||||
|
iconSize: 10.0,
|
||||||
|
onPressed: mockOnPressedFunction.handler,
|
||||||
|
icon: const Icon(Icons.link),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final RenderBox icon = tester.renderObject(find.byType(Icon));
|
||||||
|
expect(icon.size, const Size(10.0, 10.0));
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Small icons with non-null constraints can be <48dp', (WidgetTester tester) async {
|
testWidgets('Small icons with non-null constraints can be <48dp', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
wrap(
|
wrap(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user