如何在Toggle的圆形滑块上添加文字
===================

#### 问题现象

Toggle使用开关样式，如何在圆形滑块上加字？

#### 背景知识

*   [Toggle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-toggle)设置为开关样式时，支持设置包含圆形滑块半径、颜色等的[switchStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-toggle#switchstyle12)，更多设置可以使用[contentModifier](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-toggle#contentmodifier12)定制Toggle内容区。
*   组件的某些通用属性变化时，可以通过[属性动画](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-animatorproperty)实现渐变过渡效果。

#### 解决方案

Toggle的switchStyle仅支持设置圆形滑块半径或颜色，不支持添加内容，因此需要自定义Toggle内容区实现。

1.  自定义开关样式接口，并创建其实现类。
2.  构建自定义Toggle内容区。并使用属性动画animation达到与Toggle相似的动效。
3.  使用contentModifier定制Toggle内容区。

示例代码如下：

_//_ _自定义开关样式接口_
interface SwitchParam {
  circleRadius: number,
  borderRadius: number,
  selectedCircleColor: ResourceColor,
  unselectedCircleColor: ResourceColor,
  selectedColor: ResourceColor,
  unselectedColor: ResourceColor,
  selectedLabel?: string,
  unselectedLabel?: string,
  labelColor?: ResourceColor,
  labelSize?: number
}

_//_ _开关样式接口的实现类_
class MySwitchStyle implements ContentModifier<ToggleConfiguration\> {
  switchStyle: SwitchParam;

  constructor(switchStyle: SwitchParam) {
    this.switchStyle \= switchStyle;
  }

  applyContent(): WrappedBuilder<\[ToggleConfiguration\]\> {
    return wrapBuilder(buildSwitch);
  }
}
@Builder
function buildSwitch(config: ToggleConfiguration) { _// 自定义Toggle内容区。_
  Column() {
    Button(config.isOn ? _//_ _配置圆形滑块的文字。_
      (config.contentModifier as MySwitchStyle).switchStyle.selectedLabel ?? '' :
      (config.contentModifier as MySwitchStyle).switchStyle.unselectedLabel ?? '',
      { type: ButtonType.Circle })
      .fontColor((config.contentModifier as MySwitchStyle).switchStyle.labelColor)
      .fontSize((config.contentModifier as MySwitchStyle).switchStyle.labelSize)
      .height((config.contentModifier as MySwitchStyle).switchStyle.circleRadius \* 2)
      .width((config.contentModifier as MySwitchStyle).switchStyle.circleRadius \* 2)
      .padding(0)
      .backgroundColor(config.isOn ?
      (config.contentModifier as MySwitchStyle).switchStyle.selectedCircleColor :
      (config.contentModifier as MySwitchStyle).switchStyle.unselectedCircleColor)
  }
  .padding((config.contentModifier as MySwitchStyle).switchStyle.borderRadius \-
  (config.contentModifier as MySwitchStyle).switchStyle.circleRadius)
  .alignItems(config.isOn ? HorizontalAlign.Start : HorizontalAlign.End)
  .justifyContent(FlexAlign.Center)
  .backgroundColor(config.isOn ?
  (config.contentModifier as MySwitchStyle).switchStyle.selectedColor :
  (config.contentModifier as MySwitchStyle).switchStyle.unselectedColor)
  .borderRadius((config.contentModifier as MySwitchStyle).switchStyle.borderRadius)
  .height((config.contentModifier as MySwitchStyle).switchStyle.borderRadius \* 2)
  .width((config.contentModifier as MySwitchStyle).switchStyle.borderRadius \* 4 \+ 2)
  .onClick(() \=\> {
    config.triggerChange(!config.isOn);
  })
 _ // 当开关切换时，存在背景色过渡动画。_
  .animation({
    duration: 200,
    curve: Curve.Ease,
    playMode: PlayMode.Normal
  });
}
@Entry
@Component
struct ToggleTypeSwitch {
  build() {
    Column() {
      Toggle({ type: ToggleType.Switch })
        .enabled(true)
        .contentModifier(new MySwitchStyle({
          circleRadius: 9,
          borderRadius: 10,
          selectedCircleColor: Color.White,
          unselectedCircleColor: Color.White,
          selectedColor: '#ff5d7ef5',
          unselectedColor: '#e4a0b4e7',
          selectedLabel: '开',
          unselectedLabel: '关',
          labelColor: Color.Black,
          labelSize: 12
        }))
        .onChange((isOn: boolean) \=\> {
          console.info(\`Switch Log: ${isOn}\`);
        });
    }.height('100%').width('100%').justifyContent(FlexAlign.Center);
  }
}