Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions packages/flutter/lib/src/material/radio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart';
import 'constants.dart';
import 'debug.dart';
import 'material_state.dart';
import 'radio_theme.dart';
import 'theme.dart';
import 'theme_data.dart';
import 'toggleable.dart';
Expand Down Expand Up @@ -371,11 +372,12 @@ class _RadioState<T> extends State<Radio<T>> with TickerProviderStateMixin, Togg
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
final ThemeData themeData = Theme.of(context);
final RadioThemeData radioTheme = RadioTheme.of(context);
final MaterialTapTargetSize effectiveMaterialTapTargetSize = widget.materialTapTargetSize
?? themeData.radioTheme.materialTapTargetSize
?? radioTheme.materialTapTargetSize
?? themeData.materialTapTargetSize;
final VisualDensity effectiveVisualDensity = widget.visualDensity
?? themeData.radioTheme.visualDensity
?? radioTheme.visualDensity
?? themeData.visualDensity;
Size size;
switch (effectiveMaterialTapTargetSize) {
Expand All @@ -390,7 +392,7 @@ class _RadioState<T> extends State<Radio<T>> with TickerProviderStateMixin, Togg

final MaterialStateProperty<MouseCursor> effectiveMouseCursor = MaterialStateProperty.resolveWith<MouseCursor>((Set<MaterialState> states) {
return MaterialStateProperty.resolveAs<MouseCursor?>(widget.mouseCursor, states)
?? themeData.radioTheme.mouseCursor?.resolve(states)
?? radioTheme.mouseCursor?.resolve(states)
?? MaterialStateProperty.resolveAs<MouseCursor>(MaterialStateMouseCursor.clickable, states);
});

Expand All @@ -400,33 +402,33 @@ class _RadioState<T> extends State<Radio<T>> with TickerProviderStateMixin, Togg
final Set<MaterialState> inactiveStates = states..remove(MaterialState.selected);
final Color effectiveActiveColor = widget.fillColor?.resolve(activeStates)
?? _widgetFillColor.resolve(activeStates)
?? themeData.radioTheme.fillColor?.resolve(activeStates)
?? radioTheme.fillColor?.resolve(activeStates)
?? _defaultFillColor.resolve(activeStates);
final Color effectiveInactiveColor = widget.fillColor?.resolve(inactiveStates)
?? _widgetFillColor.resolve(inactiveStates)
?? themeData.radioTheme.fillColor?.resolve(inactiveStates)
?? radioTheme.fillColor?.resolve(inactiveStates)
?? _defaultFillColor.resolve(inactiveStates);

final Set<MaterialState> focusedStates = states..add(MaterialState.focused);
final Color effectiveFocusOverlayColor = widget.overlayColor?.resolve(focusedStates)
?? widget.focusColor
?? themeData.radioTheme.overlayColor?.resolve(focusedStates)
?? radioTheme.overlayColor?.resolve(focusedStates)
?? themeData.focusColor;

final Set<MaterialState> hoveredStates = states..add(MaterialState.hovered);
final Color effectiveHoverOverlayColor = widget.overlayColor?.resolve(hoveredStates)
?? widget.hoverColor
?? themeData.radioTheme.overlayColor?.resolve(hoveredStates)
?? radioTheme.overlayColor?.resolve(hoveredStates)
?? themeData.hoverColor;

final Set<MaterialState> activePressedStates = activeStates..add(MaterialState.pressed);
final Color effectiveActivePressedOverlayColor = widget.overlayColor?.resolve(activePressedStates)
?? themeData.radioTheme.overlayColor?.resolve(activePressedStates)
?? radioTheme.overlayColor?.resolve(activePressedStates)
?? effectiveActiveColor.withAlpha(kRadialReactionAlpha);

final Set<MaterialState> inactivePressedStates = inactiveStates..add(MaterialState.pressed);
final Color effectiveInactivePressedOverlayColor = widget.overlayColor?.resolve(inactivePressedStates)
?? themeData.radioTheme.overlayColor?.resolve(inactivePressedStates)
?? radioTheme.overlayColor?.resolve(inactivePressedStates)
?? effectiveActiveColor.withAlpha(kRadialReactionAlpha);

return Semantics(
Expand All @@ -446,7 +448,7 @@ class _RadioState<T> extends State<Radio<T>> with TickerProviderStateMixin, Togg
..reactionColor = effectiveActivePressedOverlayColor
..hoverColor = effectiveHoverOverlayColor
..focusColor = effectiveFocusOverlayColor
..splashRadius = widget.splashRadius ?? themeData.radioTheme.splashRadius ?? kRadialReactionRadius
..splashRadius = widget.splashRadius ?? radioTheme.splashRadius ?? kRadialReactionRadius
..downPosition = downPosition
..isFocused = states.contains(MaterialState.focused)
..isHovered = states.contains(MaterialState.hovered)
Expand Down
31 changes: 31 additions & 0 deletions packages/flutter/test/material/radio_theme_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,37 @@ void main() {
reason: 'Active pressed Radio should have overlay color: $activePressedOverlayColor',
);
});

testWidgets('Local RadioTheme can override global RadioTheme', (WidgetTester tester) async {
const Color globalThemeFillColor = Color(0xfffffff1);
const Color localThemeFillColor = Color(0xffff0000);

Widget buildRadio({required bool active}) {
return MaterialApp(
theme: ThemeData(
radioTheme: RadioThemeData(
fillColor: MaterialStateProperty.all<Color>(globalThemeFillColor),
),
),
home: Scaffold(
body: RadioTheme(
data: RadioThemeData(
fillColor: MaterialStateProperty.all<Color>(localThemeFillColor),
),
child: Radio<int>(
value: active ? 1 : 0,
groupValue: 1,
onChanged: (_) { },
),
),
),
);
}

await tester.pumpWidget(buildRadio(active: true));
await tester.pumpAndSettle();
expect(_getRadioMaterial(tester), paints..circle(color: localThemeFillColor));
});
}

Finder _findRadio() {
Expand Down