mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

fixes [Switch has some padding that leads to uncentered UI](https://github.com/flutter/flutter/issues/148498) ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( body: Center( child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ ColoredBox( color: Colors.amber, child: Switch( padding: EdgeInsets.zero, value: true, materialTapTargetSize: MaterialTapTargetSize.padded, onChanged: (bool value) {}, ), ), const SizedBox(height: 16), ColoredBox( color: Colors.amber, child: Switch( value: true, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, onChanged: (bool value) {}, ), ), ], ), ), ), ); } } ``` </details> ### Default Switch size <img width="476" alt="Screenshot 2024-07-11 at 13 25 05" src="https://github.com/flutter/flutter/assets/48603081/f9f3f6c6-443d-4bd5-81d4-5e314554b032"> ### Update Switch size using the new `Switch.padding` to address [Switch has some padding that leads to uncentered UI](https://github.com/flutter/flutter/issues/148498) <img width="476" alt="Screenshot 2024-07-11 at 13 24 40" src="https://github.com/flutter/flutter/assets/48603081/aea0717b-e852-4b8d-b703-c8c4999d4863">
236 lines
8.7 KiB
Dart
236 lines
8.7 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'template.dart';
|
|
|
|
class SwitchTemplate extends TokenTemplate {
|
|
const SwitchTemplate(super.blockName, super.fileName, super.tokens, {
|
|
super.colorSchemePrefix = '_colors.',
|
|
});
|
|
|
|
@override
|
|
String generate() => '''
|
|
class _${blockName}DefaultsM3 extends SwitchThemeData {
|
|
_${blockName}DefaultsM3(this.context);
|
|
|
|
final BuildContext context;
|
|
late final ColorScheme _colors = Theme.of(context).colorScheme;
|
|
|
|
@override
|
|
MaterialStateProperty<Color> get thumbColor {
|
|
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
if (states.contains(MaterialState.selected)) {
|
|
return ${componentColor('md.comp.switch.disabled.selected.handle')};
|
|
}
|
|
return ${componentColor('md.comp.switch.disabled.unselected.handle')};
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return ${componentColor('md.comp.switch.selected.pressed.handle')};
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return ${componentColor('md.comp.switch.selected.hover.handle')};
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return ${componentColor('md.comp.switch.selected.focus.handle')};
|
|
}
|
|
return ${componentColor('md.comp.switch.selected.handle')};
|
|
}
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return ${componentColor('md.comp.switch.unselected.pressed.handle')};
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return ${componentColor('md.comp.switch.unselected.hover.handle')};
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return ${componentColor('md.comp.switch.unselected.focus.handle')};
|
|
}
|
|
return ${componentColor('md.comp.switch.unselected.handle')};
|
|
});
|
|
}
|
|
|
|
@override
|
|
MaterialStateProperty<Color> get trackColor {
|
|
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
if (states.contains(MaterialState.selected)) {
|
|
return ${componentColor('md.comp.switch.disabled.selected.track')}.withOpacity(${opacity('md.comp.switch.disabled.track.opacity')});
|
|
}
|
|
return ${componentColor('md.comp.switch.disabled.unselected.track')}.withOpacity(${opacity('md.comp.switch.disabled.track.opacity')});
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return ${componentColor('md.comp.switch.selected.pressed.track')};
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return ${componentColor('md.comp.switch.selected.hover.track')};
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return ${componentColor('md.comp.switch.selected.focus.track')};
|
|
}
|
|
return ${componentColor('md.comp.switch.selected.track')};
|
|
}
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return ${componentColor('md.comp.switch.unselected.pressed.track')};
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return ${componentColor('md.comp.switch.unselected.hover.track')};
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return ${componentColor('md.comp.switch.unselected.focus.track')};
|
|
}
|
|
return ${componentColor('md.comp.switch.unselected.track')};
|
|
});
|
|
}
|
|
|
|
@override
|
|
MaterialStateProperty<Color?> get trackOutlineColor {
|
|
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.transparent;
|
|
}
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return ${componentColor('md.comp.switch.disabled.unselected.track.outline')}.withOpacity(${opacity('md.comp.switch.disabled.track.opacity')});
|
|
}
|
|
return ${componentColor('md.comp.switch.unselected.track.outline')};
|
|
});
|
|
}
|
|
|
|
@override
|
|
MaterialStateProperty<Color?> get overlayColor {
|
|
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.selected)) {
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return ${componentColor('md.comp.switch.selected.pressed.state-layer')};
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return ${componentColor('md.comp.switch.selected.hover.state-layer')};
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return ${componentColor('md.comp.switch.selected.focus.state-layer')};
|
|
}
|
|
return null;
|
|
}
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return ${componentColor('md.comp.switch.unselected.pressed.state-layer')};
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return ${componentColor('md.comp.switch.unselected.hover.state-layer')};
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return ${componentColor('md.comp.switch.unselected.focus.state-layer')};
|
|
}
|
|
return null;
|
|
});
|
|
}
|
|
|
|
@override
|
|
MaterialStateProperty<MouseCursor> get mouseCursor {
|
|
return MaterialStateProperty.resolveWith((Set<MaterialState> states)
|
|
=> MaterialStateMouseCursor.clickable.resolve(states));
|
|
}
|
|
|
|
@override
|
|
MaterialStatePropertyAll<double> get trackOutlineWidth => const MaterialStatePropertyAll<double>(${getToken('md.comp.switch.track.outline.width')});
|
|
|
|
@override
|
|
double get splashRadius => ${getToken('md.comp.switch.state-layer.size')} / 2;
|
|
|
|
@override
|
|
EdgeInsetsGeometry? get padding => const EdgeInsets.symmetric(horizontal: 4);
|
|
}
|
|
|
|
class _SwitchConfigM3 with _SwitchConfig {
|
|
_SwitchConfigM3(this.context)
|
|
: _colors = Theme.of(context).colorScheme;
|
|
|
|
BuildContext context;
|
|
final ColorScheme _colors;
|
|
|
|
static const double iconSize = ${getToken('md.comp.switch.unselected.icon.size')};
|
|
|
|
@override
|
|
double get activeThumbRadius => ${getToken('md.comp.switch.selected.handle.width')} / 2;
|
|
|
|
@override
|
|
MaterialStateProperty<Color> get iconColor {
|
|
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
if (states.contains(MaterialState.selected)) {
|
|
return ${componentColor('md.comp.switch.disabled.selected.icon')};
|
|
}
|
|
return ${componentColor('md.comp.switch.disabled.unselected.icon')};
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return ${componentColor('md.comp.switch.selected.pressed.icon')};
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return ${componentColor('md.comp.switch.selected.hover.icon')};
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return ${componentColor('md.comp.switch.selected.focus.icon')};
|
|
}
|
|
return ${componentColor('md.comp.switch.selected.icon')};
|
|
}
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return ${componentColor('md.comp.switch.unselected.pressed.icon')};
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return ${componentColor('md.comp.switch.unselected.hover.icon')};
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return ${componentColor('md.comp.switch.unselected.focus.icon')};
|
|
}
|
|
return ${componentColor('md.comp.switch.unselected.icon')};
|
|
});
|
|
}
|
|
|
|
@override
|
|
double get inactiveThumbRadius => ${getToken('md.comp.switch.unselected.handle.width')} / 2;
|
|
|
|
@override
|
|
double get pressedThumbRadius => ${getToken('md.comp.switch.pressed.handle.width')} / 2;
|
|
|
|
@override
|
|
double get switchHeight => switchMinSize.height + 8.0;
|
|
|
|
@override
|
|
double get switchHeightCollapsed => switchMinSize.height;
|
|
|
|
@override
|
|
double get switchWidth => 52.0;
|
|
|
|
@override
|
|
double get thumbRadiusWithIcon => ${getToken('md.comp.switch.with-icon.handle.width')} / 2;
|
|
|
|
@override
|
|
List<BoxShadow>? get thumbShadow => kElevationToShadow[0];
|
|
|
|
@override
|
|
double get trackHeight => ${getToken('md.comp.switch.track.height')};
|
|
|
|
@override
|
|
double get trackWidth => ${getToken('md.comp.switch.track.width')};
|
|
|
|
// The thumb size at the middle of the track. Hand coded default based on the animation specs.
|
|
@override
|
|
Size get transitionalThumbSize => const Size(34, 22);
|
|
|
|
// Hand coded default based on the animation specs.
|
|
@override
|
|
int get toggleDuration => 300;
|
|
|
|
// Hand coded default based on the animation specs.
|
|
@override
|
|
double? get thumbOffset => null;
|
|
|
|
@override
|
|
Size get switchMinSize => const Size(kMinInteractiveDimension, kMinInteractiveDimension - 8.0);
|
|
}
|
|
''';
|
|
|
|
}
|