HarmonyOS鸿蒙Next中如何比较优雅的处理系统组件的属性的兼容性问题

HarmonyOS鸿蒙Next中如何比较优雅的处理系统组件的属性的兼容性问题 在工程的build-profile设置了targetSdk和minSdk

"targetSdkVersion": "6.0.0(20)",
"compatibleSdkVersion": "5.0.1(13)",

设置的minSdk是13版本,targetSdk是20版本,当在代码中用了高于13版本的api时候,就要处理兼容性的问题了。

这里以NavDestinationsystemTransition属性举例,处理完兼容性的问题的代码如下:

import { deviceInfo } from "@kit.BasicServicesKit";

@ComponentV2
struct PageOne{

  @Provider('isPageShow') isPageShow :boolean = false

  @Builder
  contentBuilder(){
    //...省略的代码
  }

  build() {
    if (deviceInfo.sdkApiVersion >= 14) {
      if (deviceInfo.sdkApiVersion >= 15) {
        NavDestination() {
          this.contentBuilder()
        }
        /**
         * ...省略的属性和事件代码
         */
        .onShown(() => {
          this.isPageShow = true
        })
        .onHidden(() => {
          this.isPageShow = false
        })
        .systemTransition(NavigationSystemTransitionType.SLIDE_BOTTOM)
      } else {
        NavDestination() {
          this.contentBuilder()
        }
        /**
         * ...省略的属性和事件代码
         */
        .onShown(() => {
          this.isPageShow = true
        })
        .onHidden(() => {
          this.isPageShow = false
        })
        .systemTransition(NavigationSystemTransitionType.DEFAULT)
      }
    } else {
      NavDestination() {
        this.contentBuilder()
      }
      /**
       * ...省略的属性和事件代码
       */
      .onShown(() => {
        this.isPageShow = true
      })
      .onHidden(() => {
        this.isPageShow = false
      })
    }
  }
}

一模一样的代码要写多遍,如果要修改就要改多个地方,忘记了少改一个地方就会导致bug,简直让人崩溃😭

那如何优雅的处理这个问题呢?

答案是使用attributeModifier

import { deviceInfo } from "@kit.BasicServicesKit";
import { AttributeUpdater } from "@kit.ArkUI";

//需要处理兼容性的属性
export interface NavCompatibleAttr{
  navTransitionType?:number
}

export class NavModifier extends AttributeUpdater<NavDestinationAttribute> {
  readonly attr :NavCompatibleAttr

  constructor(attr: NavCompatibleAttr) {
    super();
    this.attr = attr;
  }

  // 首次绑定时触发initializeModifier方法,进行属性初始化
  initializeModifier(instance: NavDestinationAttribute): void {
    if (deviceInfo.sdkApiVersion >= 15) {
      if(typeof this.attr.navTransitionType === 'number'){
        instance.systemTransition(this.attr.navTransitionType)
      }
    }else if (deviceInfo.sdkApiVersion >= 14) {
      if(typeof this.attr.navTransitionType === 'number'){
        if(this.attr.navTransitionType <= NavigationSystemTransitionType.CONTENT){
          instance.systemTransition(this.attr.navTransitionType)
        }
        else {
          instance.systemTransition(NavigationSystemTransitionType.DEFAULT)
        }
      }
    }
  }
}

@ComponentV2
struct PageTwo {
  @Provider('isPageShow') isPageShow: boolean = false

  build() {
    NavDestination() {
      //...省略的代码
    }
    /**
     * ...省略的属性和事件代码
     */
    .onShown(() => {
      this.isPageShow = true
    })
    .onHidden(() => {
      this.isPageShow = false
    })
    //.systemTransition(NavigationSystemTransitionType.SLIDE_BOTTOM)
    .attributeModifier(new NavModifier({navTransitionType:7}))//SLIDE_BOTTOM的值是7,这里偷懒下
  }
}

更多关于HarmonyOS鸿蒙Next中如何比较优雅的处理系统组件的属性的兼容性问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

mark

更多关于HarmonyOS鸿蒙Next中如何比较优雅的处理系统组件的属性的兼容性问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


不错

不知道有没有更优雅的方式来处理这个兼容性的问题?

其实我最先想到的是kotlin的also扩展函数,如果arkTs支持这种就好了:

build() {
  NavDestination() {
    //...省略的代码
  }
  /**
   * ...省略的属性和事件代码
   */
  .onShown(() => {
    this.isPageShow = true
  })
  .onHidden(() => {
    this.isPageShow = false
  })
  .also((it) =>{
    if(deviceInfo.sdkApiVersion >= 15){
      it.systemTransition(NavigationSystemTransitionType.SLIDE_BOTTOM)
    }else if(deviceInfo.sdkApiVersion >= 14){
      it.systemTransition(NavigationSystemTransitionType.DEFAULT)
    }
    return it
  })

可惜我没找到类似这种的实现方式

在HarmonyOS Next中,处理系统组件属性兼容性问题,推荐使用ArkTS的条件编译或API版本判断。通过@ohos.application.Ability模块的apiVersionreleaseType来检测系统版本,再结合条件语句(如if)对不同版本使用不同的属性或组件。也可利用@ohos.compatibility模块的API兼容性检查工具,在编译时或运行时动态适配属性,避免直接使用不兼容的API。

在HarmonyOS Next中,使用attributeModifier处理系统组件属性兼容性是非常优雅的方案。你提供的示例很好地展示了如何通过自定义AttributeUpdater来封装版本判断逻辑,避免代码重复。

关键优势:

  1. 逻辑集中:将版本判断和属性设置封装在initializeModifier方法中,一处修改全局生效
  2. 类型安全:通过NavCompatibleAttr接口定义兼容性属性,确保类型正确
  3. 使用简洁:组件侧只需调用.attributeModifier(),无需重复版本判断

建议扩展:

  • 可创建统一的CompatibilityManager管理多个组件的修饰器
  • 对于常用组件,可发布为共享包供团队复用
  • 结合@Require装饰器声明API版本要求,增强可读性

这种方法符合ArkUI框架设计理念,通过修饰器模式实现关注点分离,是处理SDK版本兼容性的推荐实践。

回到顶部