HarmonyOS 4.0 应用开发快速入门之 03-样式处理
AI 摘要
样式语法
链式
属性方法以链式调用的方式配置系统组件的样式和其他属性,建议每个属性方法单独写一行。
示例:链式调用样式属性
Index 组件(src/main/ets/pages/Index.ets):
Text('Hello HarmonyOS')
.backgroundColor('red') // 背景颜色
.fontSize(50) // 字体大小
.width('100%') // 宽度
.height(100) // 高度枚举
对于系统组件,ArkUI 还为其属性预定义了一些枚举类型。
示例:设置枚举样式属性
Index 组件(src/main/ets/pages/Index.ets):
Text('Hello HarmonyOS')
.backgroundColor(Color.Blue) // 背景颜色
.textAlign(TextAlign.Center) // 对齐方式
.fontColor(Color.White) // 文本颜色样式适配
像素单位
HarmonyOS 为开发者提供 4 种像素单位,ArkTS 采用 vp 为基准数据单位。
| 名称 | 描述 |
|---|---|
| px | 物理像素单位 |
| vp | 虚拟像素单位,根据屏幕像素密度转换为屏幕物理像素 |
| fp | 字体像素 |
| lpx | 逻辑像素单位,为实际屏幕宽度与逻辑宽度的比值 |
layoutWeight
layoutWeigh 在父容器尺寸确定时,设置了 layoutWeight 属性的子元素与兄弟元素占主轴尺寸按照权重进行分配,忽略元素本身尺寸设置,表示自适应占满剩余空间。
示例:layoutWeigh
Index 组件(src/main/ets/pages/Index.ets):
Row() {
Text('请输入手机号:')
// TextInput占满行组件剩余的宽度
TextInput()
.layoutWeight(1)
}.padding(20)示例效果:
aspectRatio
aspectRadio 用于指定当前组件的宽高比。
示例:aspectRatio
Index 组件(src/main/ets/pages/Index.ets):
Image($r('app.media.avatar'))
.width(96)
.aspectRatio(1)示例效果:
复用样式
@Styles 复用样式
参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-style-0000001473856690-V2
在开发过程中会出现大量代码在进行重复样式设置,@Styles 可以帮我们进行样式复用。
- 当前 @Styles 仅支持通用属性复用和通用事件复用。
- 支持全局定义和组件内定义,同时存在组件内覆盖全局生效。
全局定义复用样式:
- 写在 struct 声明的组件外。
- 用 function 关键字声明。
- 目前仅支持当前的页面组件有效。
示例:全局定义复用样式
Index 组件(src/main/ets/pages/Index.ets):
// 全局定义复用样式
@Styles
function myStyle() {
// 支持统一样式
.backgroundColor('green')
.margin({bottom: 10})
// 支持通用事件
.onClick(() =>{
console.log('click')
})
}
@Entry
@Component
struct Index {
build() {
Row() {
Column({space : 10}) {
Button('Count--')
// 调用自定义样式
.myStyle()
Button('Count++')
// 调用自定义样式
.myStyle()
}
.alignItems(HorizontalAlign.Start)
.width('100%')
}
.height("100%")
.padding(20)
.alignItems(VerticalAlign.Top)
}
}示例效果:
组件内定义复用样式:
- 写在 struct 组件内。
- 对当前的组件有效,覆盖全局同名的复用样式。
- 不需要 function 关键字。
示例:组件内定义复用样式
Index 组件(src/main/ets/pages/Index.ets):
@Entry
@Component
struct Index {
// 组件内定义复用样式
@Styles
myStyle() {
.backgroundColor('red')
.margin({bottom: 10})
.onClick(() =>{
console.log('click')
})
}
build() {
Row() {
Column({space : 10}) {
Button('Count--')
// 调用自定义样式
.myStyle()
Button('Count++')
// 调用自定义样式
.myStyle()
}
.alignItems(HorizontalAlign.Start)
.width('100%')
}
.height("100%")
.padding(20)
.alignItems(VerticalAlign.Top)
}
}示例效果:
@Extend 复用样式
参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-extend-0000001473696678-V2
@Extend 用于扩展指定的原生组件样式,通过传参提供更灵活的样式复用。
- 使用 @Extend 装饰器修饰的函数只能是全局函数。
- @Extend 必须指定扩展的组件,且复用样式只针对该组件有效。
- 复用样式函数可以进行传参,如果参数是状态变量,状态更新后会刷新 UI。
- 参数可以是一个函数,实现复用事件且可处理不同逻辑。
示例:扩展原生组件样式
Index 组件(src/main/ets/pages/Index.ets):
@Extend(Text) // 指定扩展Text组件
function myStyle(color:string, cb:()=>void) {
.backgroundColor(color)
.padding(10)
.border({radius : 6})
.onClick(cb)
}
@Entry
@Component
struct Index {
build() {
Row() {
Column({space : 10}) {
Text('Text按钮1')
.myStyle('green', () => {
console.log('Text1 Click')
})
Text('Text按钮2')
.myStyle('red', () => {
console.log('Text2 Click')
})
}
.alignItems(HorizontalAlign.Center)
.width('100%')
}
.height("100%")
.padding(20)
.alignItems(VerticalAlign.Center)
}
}示例效果:
复用样式总结
作用不同:
- @Styles 用来定义可复用的样式和事件,只支持通用样式和通用事件。
- @Extend 用来扩展指定的原生组件的样式和事件。
定义方式不同:
- @Styles 支持全局定义和组件内定义。
- @Extend 只支持全局定义。
传参方式不同:
- @Styles 不支持传参。
- @Extend 支持传参,参数可以是一个函数。
多态样式
stateStyles
stateStyles 可以依据组件的内部状态的不同,快速设置不同样式。
ArkUI 提供四种状态:focused 获焦态、normal 正常态、pressed 按压态、disabled 禁用态。
- 在 HarmonyOS 中,页面初始化时默认第一个能获取焦点的元素会自动获取焦点。
- Button 组件可以通过 enabled 属性设置为 false,使其变成禁用态。参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V3/ts-universal-attributes-enable-0000001333321237-V3
- disabled 禁用态的样式,只有组件从正常态转变成禁用态时(如按钮点击后切换状态),样式才会生效。
- 一个非 TextInput 组件无法通过点击进入 focus 状态,可以通过 focusable 属性设置为 true,并且放在第一个位置,即可进入 focus 状态。参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V3/ts-universal-attributes-focus-0000001281001274-V3
示例:设置不同组件不同状态下的样式
Index 组件(src/main/ets/pages/Index.ets):
@Entry
@Component
struct Index {
build() {
Row() {
Column({space : 10}) {
// 可以获得获焦态的第一个元素会自动获焦,故该TextInput默认获得焦点
TextInput()
.stateStyles({
// 组件获焦态的样式
focused: {
.backgroundColor('blue')
}
})
Button('按钮')
.stateStyles({
// 组件正常态时的样式
normal: {
.backgroundColor('green')
},
// 组件按压态的样式
pressed: {
.backgroundColor('red')
}
})
TextInput()
.stateStyles({
// 当从正常态转换到禁用态时,样式生效
disabled: {
.backgroundColor('black')
}
})
}
.alignItems(HorizontalAlign.Center)
.width('100%')
}
.height("100%")
.padding(20)
.alignItems(VerticalAlign.Center)
}
}示例效果:
stateStyles + @Styles
stateStyles 可以结合 @Styles 实现样式复用。
示例:多态样式实现样式复用
Index 组件(src/main/ets/pages/Index.ets):
@Entry
@Component
struct Index {
@Styles
greenColor() {
.backgroundColor('green')
}
build() {
Row() {
Column({space : 10}) {
Button('按钮')
.stateStyles({
pressed: this.greenColor
})
}
.alignItems(HorizontalAlign.Center)
.width('100%')
}
.height("100%")
.padding(20)
.alignItems(VerticalAlign.Center)
}
}