HarmonyOS鸿蒙Next中如何封装系统组件使其自带hdsEffect效果,并在外层能随意调整样式?
HarmonyOS鸿蒙Next中如何封装系统组件使其自带hdsEffect效果,并在外层能随意调整样式? 有了新的hdsEffect效果后,要在row,column,button组件上增加发光效果和受光效果,不想在每个页面的每个使用该系统组件的地方都加上对应的代码,也不想每次使用都引入deviceInfo来判断这个api。于是我封装了一下,效果是有了,但是样式没法在使用的地方进行更改了,难不成需要对每个属性都复写一遍吗?
我封装了一个Column组件如下
import { MyModifier } from '../modifier'
import { hdsEffect } from '@kit.UIDesignKit';
import { deviceInfo } from '@kit.BasicServicesKit';
import { ViewStyle } from '../common/constants/Constants'
@Extend(Column)
function onTouchLight(cb: (type: hdsEffect.PointLightSourceType) => void) {
.onTouch((event: TouchEvent) => {
if (deviceInfo.sdkApiVersion >= 20) {
if (event.type === TouchType.Down) {
cb(hdsEffect.PointLightSourceType.BRIGHT)
} else if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
cb(hdsEffect.PointLightSourceType.NONE)
}
}
})
}
@Component
export struct MyColumn {
@BuilderParam customBuilderParam: () => void = this.customBuilder;
@Prop @Watch('showAniFun') showAni: boolean = false
@State translateY: number = 50;
@State opacityNum: number = 0;
@State index: number = 0
@State alignItems: HorizontalAlign = HorizontalAlign.Start
@State justifyContent: FlexAlign = FlexAlign.Start
@State modifier: MyModifier = new MyModifier()
@State H: string | Resource = ''
@State W: string | Resource = ''
@State OL: string | CustomBuilder | ComponentContent = ''
@Builder
customBuilder() {
}
build() {
Column() {
this.customBuilderParam()
}
.onTouchLight((type: hdsEffect.PointLightSourceType) => {
this.modifier.sourceType = type
})
.backgroundColor(ViewStyle.BgColor)
.opacity(this.opacityNum)
.translate({ y: this.translateY })
.attributeModifier(this.modifier)
.alignItems(this.alignItems)
.justifyContent(this.justifyContent)
.height(this.H)
.width(this.W)
.overlay(this.OL)
}
showAniFun() {
if (this.showAni == true) {
this.opacityNum = 0
this.translateY = 50
this.getUIContext()?.animateTo({ duration: 250, curve: 'ease-out', delay: 50 * this.index }, () => {
this.opacityNum = 1
this.translateY = 0
})
} else {
this.opacityNum = 0
this.translateY = 50
}
}
aboutToAppear(): void {
this.getUIContext()?.animateTo({ duration: 250, curve: 'ease-out' }, () => {
this.opacityNum = 1
this.translateY = 0
})
}
aboutToDisappear(): void {
this.opacityNum = 0
this.translateY = 50
}
}
modifier如下
import { deviceInfo } from '@kit.BasicServicesKit';
import { hdsEffect } from '@kit.UIDesignKit';
export class MyModifier implements AttributeModifier<CommonAttribute> {
showHDS: boolean = true
sourceType: hdsEffect.PointLightSourceType = hdsEffect.PointLightSourceType.NONE
applyNormalAttribute(instance: CommonAttribute): void {
if (deviceInfo.sdkApiVersion >= 20 && this.showHDS === true) {
instance.visualEffect(new hdsEffect.HdsEffectBuilder().pointLight({
illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER_CONTENT,
sourceType: this.sourceType
}))
}
}
}
封装是好了,但是在页面使用的时候,没法去随意使用其他属性,只能使用我预设好的一些属性。
后面该如何写?求大佬指导。
更多关于HarmonyOS鸿蒙Next中如何封装系统组件使其自带hdsEffect效果,并在外层能随意调整样式?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
使用尾随闭包能在内部的组件里绑定当前页面的对象,但是无法设置封装组件的属性。不使用尾随闭包通过传递组件方式,传递的组件无法使用$$来双向绑定,这这么破

更多关于HarmonyOS鸿蒙Next中如何封装系统组件使其自带hdsEffect效果,并在外层能随意调整样式?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,通过@Styles装饰器定义可复用的组件样式,结合@Extend装饰器扩展系统组件,封装时使用@BuilderParam动态注入hdsEffect效果。外层通过@State变量控制样式参数,实现灵活调整。
在HarmonyOS Next中,要实现封装系统组件自带hdsEffect效果并保持外部样式灵活性,建议采用以下方案:
-
使用@BuilderParam传递样式:将样式配置作为Builder参数传入,允许外部自定义。
[@Component](/user/Component) export struct MyColumn { [@BuilderParam](/user/BuilderParam) styleBuilder: () => void = () => {}; build() { Column() { // 内容 } .attributeModifier(this.modifier) .apply(this.styleBuilder) // 应用外部样式 } } -
链式调用支持:在自定义组件中暴露原始组件的方法,通过
this返回组件实例。build() { Column() { // 内容 } .attributeModifier(this.modifier) // 不封闭样式链,允许外部继续调用样式方法 } -
属性代理模式:通过@Prop接收样式值,但更推荐使用@Styles或@Extend定义可复用样式组合,将hdsEffect封装在样式扩展中。
[@Styles](/user/Styles) function hdsColumnStyle() { .attributeModifier(new MyModifier()) // 其他基础样式 } // 使用时 Column() .hdsColumnStyle() .width(100) // 外部可继续调整 -
条件渲染hdsEffect:在modifier中增加开关,允许外部通过属性控制是否启用效果。
export class MyModifier { [@Prop](/user/Prop) enableHds: boolean = true; // ... 根据enableHds条件应用效果 }
这样既封装了hdsEffect的通用逻辑,又通过ArkUI的响应式设计保持了样式的灵活性。

