Fix Local SwitchTheme
not being inherited by Switch
Widget (#97705)
This commit is contained in:
parent
17a77164d7
commit
3bba8df83b
@ -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 {
|
|||||||
/// {@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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
|||||||
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
|
|||||||
..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() {
|
|||||||
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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user