Skip to content

样式与属性

ArkUI 的属性系统:几何属性、位置属性、容器属性、文本样式、背景与边框。


1. 属性分类

属性
├── 几何属性:width/height/minWidth/maxWidth/...
├── 位置属性:position/top/left/right/bottom
├── 容器属性:justifyContent/alignItems/...
├── 文本属性:fontSize/fontColor/fontWeight/...
├── 背景属性:backgroundColor/backgroundImage
├── 边框属性:border/borderRadius
├── 阴影属性:boxShadow
├── 可见性:visibility/display
├── 动画属性:animation/clip
└── 事件属性:onClick/onLongClick/...

2. 几何属性

2.1 宽度与高度

typescript
// 固定尺寸
Text('Hello')
    .width(100)   // 100vp
    .height(50)   // 50vp

// 百分比
Image('icon')
    .width('50%')    // 父容器的 50%
    .height('auto')  // 自动(保持比例)

// 约束
Text('文本')
    .minWidth(50)      // 最小宽度
    .maxWidth(200)     // 最大宽度
    .minHeight(30)     // 最小高度
    .maxHeight(100)    // 最大高度

2.2 宽高比

typescript
// 保持 1:1 比例(正方形)
Image('icon')
    .width(100)
    .aspectRatio(1)

// 保持 16:9 比例(视频封面)
Video('cover')
    .width('100%')
    .aspectRatio(16 / 9)

3. 位置属性

3.1 position — 绝对定位

typescript
// position 相对于父容器
Stack() {
    Image('background')
        .width('100%')
        .height(200)

    // 在父容器 (0,0) 位置放置
    Text('左上')
        .position({ x: 10, y: 10 })

    // 在父容器右下角
    Text('右下')
        .position({ x: 'calc(100% - 60)', y: 'calc(100% - 30)' })
}
.width('100%')
.height(200)

3.2 offset — 相对偏移

typescript
// 相对于自身原始位置偏移
Text('偏移文本')
    .offset({ x: 10, y: -20 })  // 右移10,上移20

3.3 top/left/right/bottom

typescript
// 锚点定位
Image('icon')
    .top(20)    // 距顶部 20vp
    .right(10)  // 距右侧 10vp

4. 文本样式属性

typescript
Text('多行文本样式演示')
    .fontSize(24fp)              // 字号
    .fontColor(Color.Blue)       // 文字颜色
    .fontWeight(FontWeight.Bold) // 字重(Normal/Medium/Bold)
    .fontStyle(FontStyle.Italic) // 斜体
    .letterSpacing(2)            // 字间距
    .lineHeight(36fp)            // 行高
    .textAlign(TextAlign.Center) // 对齐方式
    .maxLines(2)                 // 最大行数
    .textOverflow({ overflow: TextOverflow.Ellipsis })  // 溢出显示 ...
    .fontFeatures([              // 字体特性
        FontFeature.LIGATURES,   // 连字
        FontFeature.SMALL_CAPS   // 小型大写字母
    ])
    .textDecorations([          // 文字装饰
        { type: TextDecorations.Underline, color: Color.Blue }
    ])
    .width('100%')

5. 背景属性

5.1 背景颜色

typescript
Column() {
    Text('内容')
}
.width('100%')
.height(200)
.backgroundColor(Color.FromRGB(0xF5, 0xF5, 0xF5))

5.2 背景图片

typescript
Column() {
    Text('背景图上的内容')
}
.width('100%')
.height(300)
.backgroundImage($r('app.media.banner'))
.backgroundImageSize(ImageSize.Cover)
.backgroundImageRepeat([ImageRepeat.NoRepeat])

5.3 渐变背景

typescript
// 线性渐变
Column() {
    Text('渐变背景')
}
.width('100%')
.height(200)
.background(
    LinearGradient({
        startPoint: { x: 0, y: 0 },
        endPoint: { x: 1, y: 1 },
        colors: [
            [Color.FromRGB(0x4A, 0x90, 0xD7), 0.0],
            [Color.FromRGB(0x1A, 0xC6, 0xB8), 1.0]
        ]
    })
)

6. 边框与圆角

6.1 边框

typescript
Text('有边框')
    .border({
        width: 1,
        color: Color.Gray,
        radius: 8  // 边框圆角
    })

// 单边边框
Text('上边框')
    .borderTop({ width: 1, color: Color.Gray })
    .borderBottom({ width: 1, color: Color.Gray })
    .borderLeft({ width: 1, color: Color.Gray })
    .borderRight({ width: 1, color: Color.Gray })

6.2 圆角

typescript
// 统一圆角
Image('avatar')
    .width(60)
    .height(60)
    .borderRadius(30)  // 50% 圆角 = 圆形

// 不同方向的圆角
Card() {
    Text('卡片内容')
}
.width('100%')
.borderRadius({
    topLeft: 12,
    topRight: 12,
    bottomLeft: 0,
    bottomRight: 0
})

7. 阴影属性

7.1 通用阴影

typescript
Text('有阴影的文本')
    .shadow({
        radius: 4,
        color: Color.FromRGBA(0, 0, 0, 0.3),
        offsetX: 0,
        offsetY: 2
    })

7.2 容器阴影

typescript
Card() {
    Text('卡片内容')
}
.width('100%')
.padding(16)
.backgroundColor(Color.White)
.shadow({
    radius: 8,
    color: Color.FromRGBA(0, 0, 0, 0.15),
    offsetX: 0,
    offsetY: 4
})

8. 可见性与裁剪

8.1 visibility

typescript
Text('可见')
    .visibility(Visibility.Visible)   // 显示
    .visibility(Visibility.Hidden)    // 隐藏(占位)
    .visibility(Visibility.None)      // 隐藏(不占位)

8.2 clip

typescript
// 裁剪超出部分
Stack() {
    Image('large-image')
        .width(200)
        .height(200)
}
.width(100)
.height(100)
.borderRadius(8)
.clip({ type: ClipType.Rect })  // 矩形裁剪
// 或
.clip({ type: ClipType.Circle })  // 圆形裁剪

9. 事件属性

9.1 点击事件

typescript
Button('点击')
    .onClick(() => {
        console.log('点击了')
    })

// 支持长按
Image('icon')
    .onClick(() => console.log('单击'))
    .onLongClick(() => console.log('长按'))

9.2 拖拽事件

typescript
Image('draggable-icon')
    .draggable(true)
    .onDragStart(() => {
        // 开始拖拽
    })
    .onDragEnd(() => {
        // 拖拽结束
    })

9.3 触摸事件

typescript
Column() {
    Text('触摸我')
}
.onTouch((event: TouchEvent) => {
    switch (event.type) {
        // 按下、移动、抬起、取消
        case TouchType.Down:
            console.log('按下')
            break
        case TouchType.Move:
            console.log(`移动: ${event.touches[0].x}, ${event.touches[0].y}`)
            break
        case TouchType.Up:
            console.log('抬起')
            break
    }
    return true  // 是否消费事件
})

10. 属性链链式调用规则

1. 属性链通过 . 连接
2. 每个属性返回当前组件
3. 可以无限链式调用
4. 最后一条属性的值覆盖前一条

// 正确
Text('Hello')
    .fontSize(24)
    .fontColor(Color.Red)
    .fontWeight(FontWeight.Bold)

// 错误:不能用;结尾打断链
Text('Hello').fontSize(24);
.fontColor(Color.Red)  // ❌ 编译错误

11. 面试高频考点

Q1: ArkUI 的属性链是什么?

回答:通过 . 连续调用组件的样式方法,每个方法返回组件本身,支持无限链式调用,简洁地设置多个属性。

Q2: visibility 的 Hidden 和 None 区别?

回答Hidden 隐藏但占位(节点在树中),None 隐藏不占位(节点从树中移除)。频繁切换用 Hidden,不频繁用 None。

Q3: clip 的作用?

回答:裁剪组件的超出部分,支持矩形(Rect)和圆形(Circle)裁剪。常用于头像圆形显示。


🐱 小猫提示:属性部分记住分类:几何/位置/文本/背景/边框/阴影/可见性/事件。面试时按类举例即可。