HarmonyOS 鸿蒙Next元服务Radio单选框组onChange回调触发多次

发布于 1周前 作者 vueper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next元服务Radio单选框组onChange回调触发多次 大佬们,今天元服务开发中遇到了两个Radio单选框(同一组)onChange回调触发了两次的问题,以下是我出问题的代码(为了容易看,去掉了样式代码):

ListItem({ style: ListItemStyle.CARD }) {
    Row() {
        Column() {
            Text("使用浅色模式")
        }
        Column() {
            Radio({ value: 'lightMode', group: 'colorModeRadioGroup' })
                .checked(true)
                .onChange((isChecked: boolean) => {
                hilog.info(0x0002, '浅色模式Radio', 'isChecked:%{public}s', isChecked)
                this.onColorModeCheckboxStateChange(!isChecked)
            })
        }
    }
}
ListItem({ style: ListItemStyle.CARD }) {
    Row() {
        Column() {
            Text("使用深色模式")
        }
        Column() {
            Radio({ value: 'darkMode', group: 'colorModeRadioGroup' })
                .checked(false)
                .onChange((isChecked: boolean) => {
                hilog.info(0x0002, '深色模式Radio', 'isChecked:%{public}s', isChecked)
            })
        }
    }
}

onColorModeCheckboxStateChange(changedPropertyName: boolean) {
    hilog.info(0x0002, 'onColorModelCheckboxStateChange', '颜色模式即将改为:%{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)
    }
}

以下是出问题的截图(没有自定义样式):

之后浅色模式Radio失效。深色模式Radio可以响应事件,每点击一次生成如下图中共8行日志,但样式不会变,就一直保持上图下方的样子。

输出的自定义日志:

按照我的理解,每一个Radio的onChange()只会调用一次,所以我只给第一个Radio的onChange里加了有效方法体,然而实际运行时函数「onColorModeCheckboxStateChange」被调用了两次(不应该只生成红圈内的日志吗,下面四行就是第二次调用了onChange()了,但看日志,像第二个Radio里也执行了第一个Radio里的onChange()),在出问题之后,我又试了将此方法改为如下:

onColorModeCheckboxStateChange(changedPropertyName: boolean) {
    hilog.info(0x0002, 'onColorModelCheckboxStateChange', '颜色模式即将改为:%{public}s', changedPropertyName)
}

那这样,才出现了我想要的效果(Radio状态切换正常,且回调只执行了第一个Radio中的onchange(),次数为1):

开发环境:DevEco Studio NEXT Release(Build Version: 5.0.3.900)

运行环境:虚拟机 & 真机

有大佬可以解答一下吗,非常感谢!


更多关于HarmonyOS 鸿蒙Next元服务Radio单选框组onChange回调触发多次的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

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

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State isChecked: boolean = true;

  onColorModeCheckboxStateChange(changedPropertyName: boolean) {
    hilog.info(0x0002, 'onColorModelCheckboxStateChange', '颜色模式即将改为:%{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("使用浅色模式")
            }

            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)
                })
            }
          }
        }

        ListItem({ style: ListItemStyle.CARD }) {
          Row() {
            Column() {
              Text("使用深色模式")
            }

            Column() {
              Radio({ value: 'darkMode', group: 'colorModeRadioGroup' })
                .checked(!this.isChecked)
                .onChange((isChecked: boolean) => {
                  hilog.info(0x0002, '深色模式Radio', 'isChecked:%{public}s', isChecked)
                })
            }
          }
        }
      }
    }
    .height('100%')
    .width('100%')
  }
}

这样写就可以实现你想要得效果了。

主要原因时调用this.getUIContext().getHostContext()?.getApplicationContext().setColorMode刷新界面深浅模式,会触发界面刷新,radio得check()属性写死,导致radio选中状态又被刷了回来,所以onchange事件触发了两次

更多关于HarmonyOS 鸿蒙Next元服务Radio单选框组onChange回调触发多次的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


感谢大佬!问题已经解决,辛苦回复,采纳啦!知道是因为调用这个方法出现的问题,但是想不到是因为这个默认值的问题。看官方文档写死的我也直接复制了,还是经验少吧😭,思维也当成了是HTML那种给个写死的默认值就不用管了哈哈。

复现问题demo:

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

@Entry
@Component
struct RadioExample {
  onColorModeCheckboxStateChange(changedPropertyName: boolean) {
    hilog.info(0x0002, 'onColorModelCheckboxStateChange', '颜色模式即将改为:%{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() {
    Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
      Column() {
        Text('使用浅色模式')
        Radio({ value: 'Radio1', group: 'radioGroup' }).checked(true)
          .radioStyle({
            checkedBackgroundColor: Color.Pink
          })
          .height(50)
          .width(50)
          .onChange((isChecked: boolean) => {
            hilog.info(0x0002, '浅色模式Radio', 'isChecked:%{public}s', isChecked)
            console.log('Radio1 status is ' + isChecked)
            this.onColorModeCheckboxStateChange(!isChecked)
          })
      }
      Column() {
        Text('使用深色模式')
        Radio({ value: 'Radio2', group: 'radioGroup' }).checked(false)
          .radioStyle({
            checkedBackgroundColor: Color.Blue
          })
          .height(50)
          .width(50)
          .onChange((isChecked: boolean) => {
            hilog.info(0x0002, '深色模式Radio', 'isChecked:%{public}s', isChecked)
            console.log('Radio2 status is ' + isChecked)
          })
      }
    }.padding({ top: 30 })
  }
}

该问题已反馈研发人员进一步分析,请耐心等待!

this.getUIContext() .getHostContext()?.getApplicationContext().setColorMode

看着像是掉了这个方法,就会触发两次刷新,

对 我已经控制变量测试发现也是这个问题,

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-radio-V5# 示例1

这个示例里面三个Radio,你跑一下,就可以感觉出来了。

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-radio-V5#onchange

可以看下文档,文档上写:“单选框选中状态改变时触发回调”,你的Radio group相同,两个Radio,选中一个,另一个就会从选中变成未选中,状态就会发生变化,然后onchange事件触发两次

感谢回答!我知道每个Radio的onChange()都会触发一次,但是我只在第一个onChange()里写了调用另一个函数的代码,第二个onChange()只是输出了一个日志,看我文章最下面日志截图“颜色模式即将改为true”,这是正常的,但是我把「onColorModeCheckboxStateChange」函数里的代码补充完整之后(最上面代码块),这个「onColorModeCheckboxStateChange」函数就被调用了两次,看日志也输出了两次。

在HarmonyOS(鸿蒙)系统中,针对Next元服务Radio单选框组onChange回调触发多次的问题,这通常是由于事件处理逻辑或UI组件状态更新不当所导致。以下是一些可能的原因及解决方案的简述:

  1. 事件绑定问题:检查Radio单选框组是否不小心被绑定了多次事件监听器,尤其是在动态添加或移除组件时。确保事件监听器只绑定一次。

  2. 状态更新循环:确认onChange回调中是否有代码直接或间接导致了组件状态的再次更新,从而触发了新的回调。避免在回调中执行可能触发自身再次被调用的操作。

  3. 组件复用问题:如果Radio单选框组是在列表或循环中被复用,确保每个实例的事件监听器是独立且正确设置的,避免事件监听器的交叉绑定。

  4. 系统或框架Bug:虽然较少见,但也有可能是鸿蒙系统或Next元服务框架本身的Bug。检查是否有相关的系统更新或补丁。

针对上述问题,可以尝试逐一排查并修正。如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html 。这将有助于进一步诊断问题并获得专业支持。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!