Unverified Commit 3bba8df8 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Fix Local `SwitchTheme` not being inherited by `Switch` Widget (#97705)

parent 17a77164
...@@ -12,6 +12,7 @@ import 'constants.dart'; ...@@ -12,6 +12,7 @@ import 'constants.dart';
import 'debug.dart'; import 'debug.dart';
import 'material_state.dart'; import 'material_state.dart';
import 'shadows.dart'; import 'shadows.dart';
import 'switch_theme.dart';
import 'theme.dart'; import 'theme.dart';
import 'theme_data.dart'; import 'theme_data.dart';
import 'toggleable.dart'; import 'toggleable.dart';
...@@ -397,9 +398,12 @@ class Switch extends StatelessWidget { ...@@ -397,9 +398,12 @@ class Switch extends StatelessWidget {
/// {@macro flutter.widgets.Focus.autofocus} /// {@macro flutter.widgets.Focus.autofocus}
final bool autofocus; final bool autofocus;
Size _getSwitchSize(ThemeData theme) { Size _getSwitchSize(BuildContext context) {
final ThemeData theme = Theme.of(context);
final SwitchThemeData switchTheme = SwitchTheme.of(context);
final MaterialTapTargetSize effectiveMaterialTapTargetSize = materialTapTargetSize final MaterialTapTargetSize effectiveMaterialTapTargetSize = materialTapTargetSize
?? theme.switchTheme.materialTapTargetSize ?? switchTheme.materialTapTargetSize
?? theme.materialTapTargetSize; ?? theme.materialTapTargetSize;
switch (effectiveMaterialTapTargetSize) { switch (effectiveMaterialTapTargetSize) {
case MaterialTapTargetSize.padded: case MaterialTapTargetSize.padded:
...@@ -410,7 +414,7 @@ class Switch extends StatelessWidget { ...@@ -410,7 +414,7 @@ class Switch extends StatelessWidget {
} }
Widget _buildCupertinoSwitch(BuildContext context) { Widget _buildCupertinoSwitch(BuildContext context) {
final Size size = _getSwitchSize(Theme.of(context)); final Size size = _getSwitchSize(context);
return Focus( return Focus(
focusNode: focusNode, focusNode: focusNode,
autofocus: autofocus, autofocus: autofocus,
...@@ -433,7 +437,7 @@ class Switch extends StatelessWidget { ...@@ -433,7 +437,7 @@ class Switch extends StatelessWidget {
return _MaterialSwitch( return _MaterialSwitch(
value: value, value: value,
onChanged: onChanged, onChanged: onChanged,
size: _getSwitchSize(Theme.of(context)), size: _getSwitchSize(context),
activeColor: activeColor, activeColor: activeColor,
activeTrackColor: activeTrackColor, activeTrackColor: activeTrackColor,
inactiveThumbColor: inactiveThumbColor, inactiveThumbColor: inactiveThumbColor,
...@@ -691,6 +695,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta ...@@ -691,6 +695,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
} }
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final SwitchThemeData switchTheme = SwitchTheme.of(context);
// Colors need to be resolved in selected and non selected states separately // Colors need to be resolved in selected and non selected states separately
// so that they can be lerped between. // so that they can be lerped between.
...@@ -698,46 +703,46 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta ...@@ -698,46 +703,46 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
final Set<MaterialState> inactiveStates = states..remove(MaterialState.selected); final Set<MaterialState> inactiveStates = states..remove(MaterialState.selected);
final Color effectiveActiveThumbColor = widget.thumbColor?.resolve(activeStates) final Color effectiveActiveThumbColor = widget.thumbColor?.resolve(activeStates)
?? _widgetThumbColor.resolve(activeStates) ?? _widgetThumbColor.resolve(activeStates)
?? theme.switchTheme.thumbColor?.resolve(activeStates) ?? switchTheme.thumbColor?.resolve(activeStates)
?? _defaultThumbColor.resolve(activeStates); ?? _defaultThumbColor.resolve(activeStates);
final Color effectiveInactiveThumbColor = widget.thumbColor?.resolve(inactiveStates) final Color effectiveInactiveThumbColor = widget.thumbColor?.resolve(inactiveStates)
?? _widgetThumbColor.resolve(inactiveStates) ?? _widgetThumbColor.resolve(inactiveStates)
?? theme.switchTheme.thumbColor?.resolve(inactiveStates) ?? switchTheme.thumbColor?.resolve(inactiveStates)
?? _defaultThumbColor.resolve(inactiveStates); ?? _defaultThumbColor.resolve(inactiveStates);
final Color effectiveActiveTrackColor = widget.trackColor?.resolve(activeStates) final Color effectiveActiveTrackColor = widget.trackColor?.resolve(activeStates)
?? _widgetTrackColor.resolve(activeStates) ?? _widgetTrackColor.resolve(activeStates)
?? theme.switchTheme.trackColor?.resolve(activeStates) ?? switchTheme.trackColor?.resolve(activeStates)
?? _defaultTrackColor.resolve(activeStates); ?? _defaultTrackColor.resolve(activeStates);
final Color effectiveInactiveTrackColor = widget.trackColor?.resolve(inactiveStates) final Color effectiveInactiveTrackColor = widget.trackColor?.resolve(inactiveStates)
?? _widgetTrackColor.resolve(inactiveStates) ?? _widgetTrackColor.resolve(inactiveStates)
?? theme.switchTheme.trackColor?.resolve(inactiveStates) ?? switchTheme.trackColor?.resolve(inactiveStates)
?? _defaultTrackColor.resolve(inactiveStates); ?? _defaultTrackColor.resolve(inactiveStates);
final Set<MaterialState> focusedStates = states..add(MaterialState.focused); final Set<MaterialState> focusedStates = states..add(MaterialState.focused);
final Color effectiveFocusOverlayColor = widget.overlayColor?.resolve(focusedStates) final Color effectiveFocusOverlayColor = widget.overlayColor?.resolve(focusedStates)
?? widget.focusColor ?? widget.focusColor
?? theme.switchTheme.overlayColor?.resolve(focusedStates) ?? switchTheme.overlayColor?.resolve(focusedStates)
?? theme.focusColor; ?? theme.focusColor;
final Set<MaterialState> hoveredStates = states..add(MaterialState.hovered); final Set<MaterialState> hoveredStates = states..add(MaterialState.hovered);
final Color effectiveHoverOverlayColor = widget.overlayColor?.resolve(hoveredStates) final Color effectiveHoverOverlayColor = widget.overlayColor?.resolve(hoveredStates)
?? widget.hoverColor ?? widget.hoverColor
?? theme.switchTheme.overlayColor?.resolve(hoveredStates) ?? switchTheme.overlayColor?.resolve(hoveredStates)
?? theme.hoverColor; ?? theme.hoverColor;
final Set<MaterialState> activePressedStates = activeStates..add(MaterialState.pressed); final Set<MaterialState> activePressedStates = activeStates..add(MaterialState.pressed);
final Color effectiveActivePressedOverlayColor = widget.overlayColor?.resolve(activePressedStates) final Color effectiveActivePressedOverlayColor = widget.overlayColor?.resolve(activePressedStates)
?? theme.switchTheme.overlayColor?.resolve(activePressedStates) ?? switchTheme.overlayColor?.resolve(activePressedStates)
?? effectiveActiveThumbColor.withAlpha(kRadialReactionAlpha); ?? effectiveActiveThumbColor.withAlpha(kRadialReactionAlpha);
final Set<MaterialState> inactivePressedStates = inactiveStates..add(MaterialState.pressed); final Set<MaterialState> inactivePressedStates = inactiveStates..add(MaterialState.pressed);
final Color effectiveInactivePressedOverlayColor = widget.overlayColor?.resolve(inactivePressedStates) final Color effectiveInactivePressedOverlayColor = widget.overlayColor?.resolve(inactivePressedStates)
?? theme.switchTheme.overlayColor?.resolve(inactivePressedStates) ?? switchTheme.overlayColor?.resolve(inactivePressedStates)
?? effectiveActiveThumbColor.withAlpha(kRadialReactionAlpha); ?? effectiveActiveThumbColor.withAlpha(kRadialReactionAlpha);
final MaterialStateProperty<MouseCursor> effectiveMouseCursor = MaterialStateProperty.resolveWith<MouseCursor>((Set<MaterialState> states) { final MaterialStateProperty<MouseCursor> effectiveMouseCursor = MaterialStateProperty.resolveWith<MouseCursor>((Set<MaterialState> states) {
return MaterialStateProperty.resolveAs<MouseCursor?>(widget.mouseCursor, states) return MaterialStateProperty.resolveAs<MouseCursor?>(widget.mouseCursor, states)
?? theme.switchTheme.mouseCursor?.resolve(states) ?? switchTheme.mouseCursor?.resolve(states)
?? MaterialStateProperty.resolveAs<MouseCursor>(MaterialStateMouseCursor.clickable, states); ?? MaterialStateProperty.resolveAs<MouseCursor>(MaterialStateMouseCursor.clickable, states);
}); });
...@@ -763,7 +768,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta ...@@ -763,7 +768,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
..reactionColor = effectiveActivePressedOverlayColor ..reactionColor = effectiveActivePressedOverlayColor
..hoverColor = effectiveHoverOverlayColor ..hoverColor = effectiveHoverOverlayColor
..focusColor = effectiveFocusOverlayColor ..focusColor = effectiveFocusOverlayColor
..splashRadius = widget.splashRadius ?? theme.switchTheme.splashRadius ?? kRadialReactionRadius ..splashRadius = widget.splashRadius ?? switchTheme.splashRadius ?? kRadialReactionRadius
..downPosition = downPosition ..downPosition = downPosition
..isFocused = states.contains(MaterialState.focused) ..isFocused = states.contains(MaterialState.focused)
..isHovered = states.contains(MaterialState.hovered) ..isHovered = states.contains(MaterialState.hovered)
......
...@@ -419,6 +419,49 @@ void main() { ...@@ -419,6 +419,49 @@ void main() {
reason: 'Active pressed Switch should have overlay color: $activePressedOverlayColor', reason: 'Active pressed Switch should have overlay color: $activePressedOverlayColor',
); );
}); });
testWidgets('Local SwitchTheme can override global SwitchTheme', (WidgetTester tester) async {
const Color globalThemeThumbColor = Color(0xfffffff1);
const Color globalThemeTrackColor = Color(0xfffffff2);
const Color localThemeThumbColor = Color(0xffff0000);
const Color localThemeTrackColor = Color(0xffff0000);
Widget buildSwitch({bool selected = false, bool autofocus = false}) {
return MaterialApp(
theme: ThemeData(
switchTheme: SwitchThemeData(
thumbColor: MaterialStateProperty.all<Color>(globalThemeThumbColor),
trackColor: MaterialStateProperty.all<Color>(globalThemeTrackColor),
),
),
home: Scaffold(
body: SwitchTheme(
data: SwitchThemeData(
thumbColor: MaterialStateProperty.all<Color>(localThemeThumbColor),
trackColor: MaterialStateProperty.all<Color>(localThemeTrackColor),
),
child: Switch(
value: selected,
onChanged: (bool value) {},
autofocus: autofocus,
),
),
),
);
}
await tester.pumpWidget(buildSwitch(selected: true));
await tester.pumpAndSettle();
expect(
_getSwitchMaterial(tester),
paints
..rrect(color: localThemeTrackColor)
..circle()
..circle()
..circle()
..circle(color: localThemeThumbColor),
);
});
} }
Future<void> _pointGestureToSwitch(WidgetTester tester) async { Future<void> _pointGestureToSwitch(WidgetTester tester) async {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment