Switch.adaptive constructor

const Switch.adaptive({
  1. Key? key,
  2. required bool value,
  3. required ValueChanged<bool>? onChanged,
  4. @Deprecated('Use activeThumbColor or activeTrackColor instead. ' 'This feature was deprecated after v3.31.0-2.0.pre.') Color? activeColor,
  5. Color? activeThumbColor,
  6. Color? activeTrackColor,
  7. Color? inactiveThumbColor,
  8. Color? inactiveTrackColor,
  9. ImageProvider<Object>? activeThumbImage,
  10. ImageErrorListener? onActiveThumbImageError,
  11. ImageProvider<Object>? inactiveThumbImage,
  12. ImageErrorListener? onInactiveThumbImageError,
  13. MaterialTapTargetSize? materialTapTargetSize,
  14. WidgetStateProperty<Color?>? thumbColor,
  15. WidgetStateProperty<Color?>? trackColor,
  16. WidgetStateProperty<Color?>? trackOutlineColor,
  17. WidgetStateProperty<double?>? trackOutlineWidth,
  18. WidgetStateProperty<Icon?>? thumbIcon,
  19. DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  20. MouseCursor? mouseCursor,
  21. Color? focusColor,
  22. Color? hoverColor,
  23. WidgetStateProperty<Color?>? overlayColor,
  24. double? splashRadius,
  25. FocusNode? focusNode,
  26. ValueChanged<bool>? onFocusChange,
  27. bool autofocus = false,
  28. EdgeInsetsGeometry? padding,
  29. bool? applyCupertinoTheme,
})

Creates an adaptive Switch based on whether the target platform is iOS or macOS, following Material design's Cross-platform guidelines.

Creates a switch that looks and feels native when the ThemeData.platform is iOS or macOS, otherwise a Material Design switch is created.

To provide a custom switch theme that's only used by this factory constructor, pass a custom Adaptation<SwitchThemeData> class to the adaptations parameter of ThemeData. This can be useful in situations where you don't want the overall ThemeData.switchTheme to apply when this adaptive constructor is used.

This sample shows how to create and use subclasses of Adaptation that define adaptive SwitchThemeDatas.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [Switch.adaptive].

void main() => runApp(const SwitchApp());

class SwitchApp extends StatefulWidget {
  const SwitchApp({super.key});

  @override
  State<SwitchApp> createState() => _SwitchAppState();
}

class _SwitchAppState extends State<SwitchApp> {
  bool isMaterial = true;
  bool isCustomized = false;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = ThemeData(
      platform: isMaterial ? .android : .iOS,
      adaptations: <Adaptation<Object>>[
        if (isCustomized) const _SwitchThemeAdaptation(),
      ],
    );
    final ButtonStyle style = OutlinedButton.styleFrom(
      fixedSize: const Size(220, 40),
    );

    return MaterialApp(
      theme: theme,
      home: Scaffold(
        appBar: AppBar(title: const Text('Adaptive Switches')),
        body: Column(
          mainAxisAlignment: .center,
          children: <Widget>[
            OutlinedButton(
              style: style,
              onPressed: () {
                setState(() {
                  isMaterial = !isMaterial;
                });
              },
              child: isMaterial
                  ? const Text('Show cupertino style')
                  : const Text('Show material style'),
            ),
            OutlinedButton(
              style: style,
              onPressed: () {
                setState(() {
                  isCustomized = !isCustomized;
                });
              },
              child: isCustomized
                  ? const Text('Remove customization')
                  : const Text('Add customization'),
            ),
            const SizedBox(height: 20),
            const SwitchWithLabel(label: 'enabled', enabled: true),
            const SwitchWithLabel(label: 'disabled', enabled: false),
          ],
        ),
      ),
    );
  }
}

class SwitchWithLabel extends StatefulWidget {
  const SwitchWithLabel({
    super.key,
    required this.enabled,
    required this.label,
  });

  final bool enabled;
  final String label;

  @override
  State<SwitchWithLabel> createState() => _SwitchWithLabelState();
}

class _SwitchWithLabelState extends State<SwitchWithLabel> {
  bool active = true;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: .center,
      children: <Widget>[
        Container(
          width: 150,
          padding: const .only(right: 20),
          child: Text(widget.label),
        ),
        Switch.adaptive(
          value: active,
          onChanged: !widget.enabled
              ? null
              : (bool value) {
                  setState(() {
                    active = value;
                  });
                },
        ),
      ],
    );
  }
}

class _SwitchThemeAdaptation extends Adaptation<SwitchThemeData> {
  const _SwitchThemeAdaptation();

  @override
  SwitchThemeData adapt(ThemeData theme, SwitchThemeData defaultValue) {
    switch (theme.platform) {
      case .android:
      case .fuchsia:
      case .linux:
      case .windows:
        return defaultValue;
      case .iOS:
      case .macOS:
        return const SwitchThemeData(
          thumbColor: WidgetStateProperty<Color?>.fromMap(<WidgetState, Color>{
            WidgetState.selected: Colors.yellow,
            // Resolves to null if not selected, deferring to default values.
          }),
          trackColor: WidgetStatePropertyAll<Color>(Colors.brown),
        );
    }
  }
}

The target platform is based on the current Theme: ThemeData.platform.

Implementation

// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// {@macro material_ui.dartpad_guide}
///
/// {@example /example/lib/switch/switch.4.dart#body}
///
/// </callout-box>
///
/// The target platform is based on the current [Theme]: [ThemeData.platform].
const Switch.adaptive({
  super.key,
  required this.value,
  required this.onChanged,
  @Deprecated(
    'Use activeThumbColor or activeTrackColor instead. '
    'This feature was deprecated after v3.31.0-2.0.pre.',
  )
  this.activeColor,
  this.activeThumbColor,
  this.activeTrackColor,
  this.inactiveThumbColor,
  this.inactiveTrackColor,
  this.activeThumbImage,
  this.onActiveThumbImageError,
  this.inactiveThumbImage,
  this.onInactiveThumbImageError,
  this.materialTapTargetSize,
  this.thumbColor,
  this.trackColor,
  this.trackOutlineColor,
  this.trackOutlineWidth,
  this.thumbIcon,
  this.dragStartBehavior = DragStartBehavior.start,
  this.mouseCursor,
  this.focusColor,
  this.hoverColor,
  this.overlayColor,
  this.splashRadius,
  this.focusNode,
  this.onFocusChange,
  this.autofocus = false,
  this.padding,
  this.applyCupertinoTheme,
}) : assert(activeThumbImage != null || onActiveThumbImageError == null),
     assert(inactiveThumbImage != null || onInactiveThumbImageError == null),
     _switchType = _SwitchType.adaptive;