随着HarmonyOS(鸿蒙操作系统)的不断发展,开发者们面临着越来越多的应用场景和技术难题。本文将探讨如何利用HarmonyOS提供的特性,特别是API 11中的attributeModifier,以及一些技巧来克服样式抽离和组件状态管理方面的挑战。

一、样式抽离与跨页面复用

在HarmonyOS应用开发过程中,开发者常常希望将一些通用样式抽离出来,以便在多个页面间重用。然而,默认情况下,HarmonyOS提供的@Styles并不支持跨页面使用。为了解决这个问题,HarmonyOS API 11引入了attributeModifier特性,允许开发者创建可复用的样式定义。

通过attributeModifier,开发者可以在一个地方定义一组属性,然后在不同的组件中应用这些属性,从而实现了样式的集中管理和复用。这种方式不仅提高了代码的可维护性,还使得样式修改变得更加简单高效。

鸿蒙应用示例:利用attributeModifier解决样式抽离与组件状态管理_复用

src/main/ets/utils/MyStyles.ets

//输入框样式
export class MyInputModifier implements AttributeModifier<TextInputAttribute> {
  inputValue: string = ""

  applyNormalAttribute(instance: TextInputAttribute): void {
    instance.width('524.31lpx')
    instance.height('70lpx')
    instance.fontSize('27lpx')
    instance.backgroundColor("#ffffff")

  }
}

//搜索栏样式
export class MyRowModifier implements AttributeModifier<RowAttribute> {
  applyNormalAttribute(instance: RowAttribute): void {
    instance.width('100%')
    instance.justifyContent(FlexAlign.SpaceBetween)
    instance.backgroundColor(Color.Gray)
    instance.padding({
      left: '37lpx',
      top: '11lpx',
      bottom: '11lpx',
      right: '15lpx'
    })
  }
}

src/main/ets/pages/Page135.ets

import { MyInputModifier, MyRowModifier } from '../utils/MyStyles'

@Entry
@Component
struct Page135 {
  @State myInputModifier: MyInputModifier = new MyInputModifier()
  @State myRowModifier: MyRowModifier = new MyRowModifier()

  build() {
    Column() {
      Row() {
        TextInput({ placeholder: '请输入内容' }).attributeModifier(this.myInputModifier)
          .onChange((value) => {
            this.myInputModifier.inputValue = value
          })

        Button('搜索').onClick(() => {

        })
      }.attributeModifier(this.myRowModifier)
    }
  }
}

注意事项

尽管attributeModifier提供了一个强大的工具来管理样式,但在使用时仍需注意一些限制。例如,在定义组件属性时,如applyNormalAttribute方法中,不应该尝试实现如onClick这样的交互逻辑。如果这样做,可能会遇到“SourceMap is not initialized yet”的错误。

正确的做法是,在组件定义中专注于样式和布局属性的设置,而将事件处理逻辑分离出来,通过其他方式(如组件自身的事件监听器)来实现。

二、TextInput与Attribute Modifier的兼容性

当使用TextInput组件与attributeModifier结合时,可能会遇到一些意想不到的问题。比如,在某些情况下,输入框的样式可能会发生意料之外的变化。为了防止这种情况的发生,建议从TextInput组件中移除text属性,并改用onChange事件来监听输入变化。

这样做的好处在于,它不仅可以避免因样式冲突导致的问题,还可以确保输入状态的一致性,提供更好的用户体验。

三、组件状态管理与标签设置

对于那些需要在页面之间传递额外信息的应用场景,如设置组件标签(tag),HarmonyOS并没有像Android那样的setTag方法。不过,可以利用AttributeModifier来封装类似的功能。如果还需要在页面销毁后再恢复上一次的状态,可以考虑使用static变量来保存这些信息。

这种方法特别适用于拥有大量输入组件的页面,因为它可以帮助我们跟踪各个组件的状态,从而在用户重新进入页面时能够快速恢复之前的状态。

鸿蒙应用示例:利用attributeModifier解决样式抽离与组件状态管理_复用_02

src/main/ets/util/MyUtils.ets

//输入框样式
export class MyInputModifier implements AttributeModifier<TextInputAttribute> {
  private static oldInputValueMap: Map<string,string> = new Map<string,string>()
  private inputValue: string = ""
  private inputName :string = ""

  constructor(inputName:string) {
    this.inputName = inputName
    if(MyInputModifier.oldInputValueMap[inputName]){
      this.inputValue = MyInputModifier.oldInputValueMap[inputName]
    }
  }

  setInputValue(inputValue: string) {
    this.inputValue = inputValue
    MyInputModifier.oldInputValueMap[this.inputName] = inputValue
  }

  getInputValue() {
    return this.inputValue
  }

  applyNormalAttribute(instance: TextInputAttribute): void {
    instance.width('524.31lpx')
    instance.height('70lpx')
    instance.fontSize('27lpx')
    instance.backgroundColor("#ffffff")

  }
}

//搜索栏样式
export class MyRowModifier implements AttributeModifier<RowAttribute> {
  applyNormalAttribute(instance: RowAttribute): void {
    instance.width('100%')
    instance.justifyContent(FlexAlign.SpaceBetween)
    instance.backgroundColor("#ffffff")
    instance.padding({
      left: '37lpx',
      top: '11lpx',
      bottom: '11lpx',
      right: '15lpx'
    })
  }
}

src/main/ets/pages/Page008.ets

import { MyInputModifier, MyRowModifier } from '../util/MyUtils'
import { router } from '@kit.ArkUI'

@Entry
@Component
struct Page008 {
  @State myInputModifier_1: MyInputModifier = new MyInputModifier("输入框1")
  @State myInputModifier_2: MyInputModifier = new MyInputModifier("输入框2")
  @State myRowModifier: MyRowModifier = new MyRowModifier()
  aboutToAppear(): void {
  }
  build() {
    Column() {
      Row() {
        TextInput({ placeholder: '请输入内容', text: this.myInputModifier_1.getInputValue() })
          .attributeModifier(this.myInputModifier_1)
          .onChange((value) => {
            this.myInputModifier_1.setInputValue(value)
          })
      }.attributeModifier(this.myRowModifier)


      Row() {
        TextInput({ placeholder: '请输入内容', text: this.myInputModifier_2.getInputValue() })
          .attributeModifier(this.myInputModifier_2)
          .onChange((value) => {
            this.myInputModifier_2.setInputValue(value)
          })
      }.attributeModifier(this.myRowModifier)
      Button('返回上一页').onClick(()=>{
        router.back()
      })
    }
  }
}

src/main/ets/pages/Page007.ets

import { router } from '@kit.ArkUI'

@Entry
@Component
struct Page007 {

  build() {
    Row() {
      Column() {
        Text("跳转到下一页")
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(()=>{
            router.pushUrl({url:'pages/Page008'})
          })
      }
      .width('100%')
    }
    .height('100%')
  }



}

结论

通过对HarmonyOS特性的深入理解和灵活运用,我们可以有效地解决样式抽离、组件状态管理和跨页面复用等常见开发难题。attributeModifier作为API 11中的一个重要特性,为开发者提供了强大的工具来提高代码质量、简化样式管理,并增强用户体验。随着HarmonyOS平台的发展,相信会有更多类似的创新技术帮助开发者构建更加优秀且具有竞争力的应用程序。