render method

  1. @override
Widget render(
  1. RSwitchRenderRequest request
)

Render a switch with the given request.

Implementation

@override
Widget render(RSwitchRenderRequest request) {
  final state = request.state;
  final spec = request.spec;
  final tokens = _resolveTokens(request);

  final motionTheme = HeadlessThemeProvider.of(request.context)
          ?.capability<HeadlessMotionTheme>() ??
      HeadlessMotionTheme.material;

  final animationDuration = tokens.motion?.stateChangeDuration ??
      motionTheme.button.stateChangeDuration;
  final thumbToggleDuration =
      tokens.motion?.thumbToggleDuration ?? animationDuration;

  final isDragging = state.isDragging;
  final dragT = state.dragT;
  final isOn = spec.value;
  final isRtl = Directionality.of(request.context) == TextDirection.rtl;

  final Color trackColor;
  final Color thumbColor;
  final Color outlineColor;
  final double outlineWidth;

  if (isDragging && dragT != null) {
    trackColor = Color.lerp(
      tokens.inactiveTrackColor,
      tokens.activeTrackColor,
      dragT,
    )!;
    thumbColor = Color.lerp(
      tokens.inactiveThumbColor,
      tokens.activeThumbColor,
      dragT,
    )!;
    outlineColor = Color.lerp(
      tokens.trackOutlineColor,
      Colors.transparent,
      dragT,
    )!;
    outlineWidth = tokens.trackOutlineWidth * (1 - dragT);
  } else {
    trackColor = isOn ? tokens.activeTrackColor : tokens.inactiveTrackColor;
    thumbColor = isOn ? tokens.activeThumbColor : tokens.inactiveThumbColor;
    outlineColor = isOn ? Colors.transparent : tokens.trackOutlineColor;
    outlineWidth = isOn ? 0.0 : tokens.trackOutlineWidth;
  }

  final visualValue = state.dragVisualValue ?? spec.value;
  final statesForIcon = state.toWidgetStates();
  if (visualValue != state.isSelected) {
    if (visualValue) {
      statesForIcon.add(WidgetState.selected);
    } else {
      statesForIcon.remove(WidgetState.selected);
    }
  }
  final thumbIcon = tokens.thumbIcon?.resolve(statesForIcon);
  final hasIcon = thumbIcon != null;

  final thumbIconColor =
      visualValue ? tokens.activeTrackColor : tokens.inactiveTrackColor;

  final stateLayerStates = state.toWidgetStates();
  final stateLayerColor = tokens.stateLayerColor.resolve(stateLayerStates);
  final showStateLayer =
      state.isPressed || state.isHovered || state.isFocused || isDragging;

  Widget result = MaterialSwitchTrackAndThumb(
    tokens: tokens,
    trackColor: trackColor,
    outlineColor: outlineColor,
    outlineWidth: outlineWidth,
    thumbColor: thumbColor,
    thumbIcon: thumbIcon,
    thumbIconColor: thumbIconColor,
    hasIcon: hasIcon,
    isDragging: isDragging,
    isPressed: state.isPressed,
    isRtl: isRtl,
    visualValue: visualValue,
    dragT: state.dragT,
    animationDuration: animationDuration,
    thumbToggleDuration: thumbToggleDuration,
    stateLayerColor: stateLayerColor,
    showStateLayer: showStateLayer,
    slots: request.slots,
    spec: spec,
    state: state,
  );

  final minWidth = request.constraints?.minWidth ?? 0;
  final minHeight = request.constraints?.minHeight ?? 0;
  final desiredWidth =
      math.max(tokens.trackSize.width, tokens.minTapTargetSize.width);
  final desiredHeight =
      math.max(tokens.trackSize.height, tokens.minTapTargetSize.height);
  result = SizedBox(
    width: math.max(desiredWidth, minWidth),
    height: math.max(desiredHeight, minHeight),
    child: Center(child: result),
  );

  if (state.isDisabled && tokens.disabledOpacity < 1) {
    result = Opacity(
      opacity: tokens.disabledOpacity,
      child: result,
    );
  }

  return result;
}