基于单选框的深浅色模式切换失败
===============

#### 问题现象

在通过单选框交互实现深浅色主题实时切换的过程中，界面行为异常。具体操作和现象如下：从浅色模式时切换到深色模式时，浅色模式的Radio仍显示为选中状态，而深色模式的Radio无法选中，但实际已经切换成深色模式了。

问题代码如下：

import { hilog } from '@kit.PerformanceAnalysisKit';
import { ConfigurationConstant } from '@kit.AbilityKit';

@Entry
@Component
struct RadioButton {
  build() {
    Column() {
      List() {
        ListItem({ style: ListItemStyle.CARD }) {
          Row() {
            Column() {
              Text('使用浅色模式')
                .fontColor(Color.White);
            };

            Column() {
              Radio({ value: 'lightMode', group: 'colorModeRadioGroup' })
                .checked(true)
                .onChange((isChecked: boolean) => {
                  hilog.info(0x0002, '浅色模式Radio', 'isChecked:%{public}s', isChecked);
                  this.onColorModeCheckboxStateChange(!isChecked);
                });
            };
          };
        }.width('92%')
        .margin({ top: 16 })
        .backgroundColor('#0A59F7')
        .borderRadius(20);

        ListItem({ style: ListItemStyle.CARD }) {
          Row() {
            Column() {
              Text('使用深色模式')
                .fontColor(Color.White);
            };

            Column() {
              Radio({ value: 'darkMode', group: 'colorModeRadioGroup' })
                .checked(false)
                .onChange((isChecked: boolean) => {
                  hilog.info(0x0002, '深色模式Radio', 'isChecked:%{public}s', isChecked);
                });
            };
          };
        }
        .width('92%')
        .margin({ top: 16 })
        .backgroundColor('#0A59F7')
        .borderRadius(20);
      };
    }
    .height('100%')
    .width('100%');
  }

  onColorModeCheckboxStateChange(changedPropertyName: boolean) {
    hilog.info(0x0002, 'onColorModeCheckboxStateChange', '颜色模式即将改为:%{public}s', changedPropertyName);
    if (changedPropertyName) {
      this.getUIContext()
        .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR\_MODE\_LIGHT);
    } else {
      this.getUIContext()
        .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR\_MODE\_DARK);
    }
  }
}

问题现象如下：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/1c/v3/xzvUchScRqa9HAmODE6w_Q/zh-cn_image_0000002628602660.png?HW-CC-KV=V1&HW-CC-Date=20260709T133947Z&HW-CC-Expire=86400&HW-CC-Sign=03887B2E55F1900AB95051BC34D6CA761CF6CD3ED3D2E5E289DEF48B986D5878 "点击放大")

#### 背景知识

[Radio](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-common-components-radio-button)是单选框组件，通常用于提供相应的用户交互选择项，同一组的Radio中只有一个可以被选中。

#### 问题定位

通过分析问题代码可知：

*   当调用[setColorMode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-uiabilitycontext#setcolormode18)切换颜色模式时，组件重新渲染，通过属性[checked](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-radio#checked)强制重置状态。
*   [onChange](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-radio#onchange)回调被频繁触发，但isChecked的值与实际颜色模式不一致。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/0b/v3/jTiRDiDoQgSkqCESwR_y2w/zh-cn_image_0000002658841931.png?HW-CC-KV=V1&HW-CC-Date=20260709T133947Z&HW-CC-Expire=86400&HW-CC-Sign=92BF87E4674493DE8CE2BF27A4C5A9068EE7245A8931FB7A95C9990EEB6B5B33 "点击放大")
    
*   切换到深色模式后，Radio.checked仍为true，状态冲突。

代码逻辑分析：

*   硬编码的checked属性：Radio.checked的值始终为固定值，未与颜色模式状态动态绑定。组件重新渲染时，checked被强制重置为硬编码值，导致状态冲突。
    
    Radio({ value: 'lightMode', group: 'colorModeRadioGroup' }).checked(true)
    Radio({ value: 'darkMode', group: 'colorModeRadioGroup' }).checked(false)
    
*   onChange回调逻辑错误：!isChecked导致逻辑反转，用户点击浅色模式的Radio会切换到深色模式，但界面刷新后checked被重置为true，形成状态冲突。onChange回调被反复触发，导致无限循环。
    
    .onChange((isChecked: boolean) => {
      this.onColorModeCheckboxStateChange(!isChecked);
    })
    

#### 分析结论

由于调用this.getUIContext().getHostContext()?.getApplicationContext().setColorMode()刷新界面深浅模式时，会触发组件重新渲染；而Radio组件的check()属性被硬编码为固定值，导致其选中状态在界面刷新后被强制重置，从而引发onChange回调频繁触发，切换深色模式后浅色模式的Radio组件状态同步异常。

#### 修改建议

原始问题的核心是Radio的属性checked被硬编码，导致状态无法同步。可通过@State装饰器将isChecked与UI动态绑定，代码如下：

*   this.isChecked控制浅色模式的选中状态。
*   !this.isChecked控制深色模式的选中状态，两者互斥。
*   避免硬编码，确保Radio.checked始终与状态同步。

Radio({ value: 'lightMode', group: 'colorModeRadioGroup' })
  .checked(this.isChecked)

Radio({ value: 'darkMode', group: 'colorModeRadioGroup' })
  .checked(!this.isChecked)

完整代码如下：

import { hilog } from '@kit.PerformanceAnalysisKit';
import { ConfigurationConstant } from '@kit.AbilityKit';

@Entry
@Component
struct RadioButton {
  @State isChecked: boolean = true;

  onColorModeCheckboxStateChange(changedPropertyName: boolean) {
    hilog.info(0x0002, 'onColorModeCheckboxStateChange', '颜色模式即将改为:%{public}s', changedPropertyName);
    if (changedPropertyName) {
      this.getUIContext()
        .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR\_MODE\_LIGHT);
    } else {
      this.getUIContext()
        .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR\_MODE\_DARK);
    }
  }

  build() {
    RelativeContainer() {
      List() {
        ListItem({ style: ListItemStyle.CARD }) {
          Row() {
            Column() {
              Text('使用浅色模式')
                .fontColor(Color.White);
            };

            Column() {
              Radio({ value: 'lightMode', group: 'colorModeRadioGroup' })
                .checked(this.isChecked)
                .onChange((isChecked: boolean) => {
                  this.isChecked = isChecked;
                  hilog.info(0x0002, '浅色模式Radio', 'isChecked:%{public}s', isChecked);
                  this.onColorModeCheckboxStateChange(isChecked);
                });
            };
          };
        }
        .margin({ top: 16 })
        .width('92%')
        .backgroundColor(this.isChecked ? '#0A59F7' : '#317AF7')
        .borderRadius(35);

        ListItem({ style: ListItemStyle.CARD }) {
          Row() {
            Column() {
              Text('使用深色模式')
                .fontColor(Color.White);
            };

            Column() {
              Radio({ value: 'darkMode', group: 'colorModeRadioGroup' })
                .checked(!this.isChecked)
                .onChange((isChecked: boolean) => {
                  hilog.info(0x0002, '深色模式Radio', 'isChecked:%{public}s', isChecked);
                });
            };
          };
        }
        .width('92%')
        .margin({ top: 16 })
        .backgroundColor(this.isChecked ? '#0A59F7' : '#317AF7')
        .borderRadius(35);
      };
    }
    .height('100%')
    .width('100%');
  }
}

修正效果如下：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/76/v3/DYNJIA24Spydl48hUWzWeQ/zh-cn_image_0000002628762562.png?HW-CC-KV=V1&HW-CC-Date=20260709T133947Z&HW-CC-Expire=86400&HW-CC-Sign=EFBFCCE133613EA8C7951CB278B0624271031721E6755B92215358CF49245D4C "点击放大")