Skip to content

ArkUI 内置组件

ArkUI 提供了丰富的内置组件,涵盖文本、图片、输入、列表、容器、弹窗等所有常见 UI 元素。


1. 组件分类总览

内置组件
├── 基础组件:Text / Image / Button / Divider
├── 输入组件:TextInput / TextArea / Checkbox / Switch / Slider
├── 容器组件:Column / Row / Stack / Flex / Grid / RelativeContainer
├── 列表组件:List / ListItem / Grid / GridItem / Swiper
├── 滚动组件:Scroll / ListScroller / Refresh
├── 弹窗组件:Dialog / Popup / ActionSheet / CustomDialog
├── 导航组件:Navigation / NavPathStack / NavDestination
└── 媒体组件:Video / Audio / Canvas

2. 基础组件

2.1 Text — 文本

typescript
Text('Hello HarmonyOS')
    .fontSize(24fp)
    .fontColor(Color.Blue)
    .fontWeight(FontWeight.Bold)
    .fontStyle(FontStyle.Italic)
    .textDecorations([TextDecorations.Underline])
    .maxLines(1)
    .textOverflow({ overflow: TextOverflow.Ellipsis })
    .width('100%')
    .textAlign(TextAlign.Start)
    .lineHeight(36fp)
    .margin({ top: 10, bottom: 10 })

💡 Text 是 ArkUI 中最常用的组件,掌握其全部样式属性。

2.2 Image — 图片

typescript
Image($r('app.media.icon'))
    .width(100vp)
    .height(100vp)
    .borderRadius(12vp)  // 圆形图片:borderRadius = width/2
    .objectFit(ImageFit.Contain)
    .onClick(() => {
        console.log('图片点击')
    })
objectFit 值效果
Fill拉伸填充(可能变形)
Contain完整显示(保持比例)
Cover填满容器(可能裁剪)
ScaleDown缩小到Contain

2.3 Button — 按钮

typescript
Button('提交')
    .width('100%')
    .height(48vp)
    .fontSize(16fp)
    .backgroundColor(Color.Blue)
    .fontColor(Color.White)
    .borderRadius(24vp)
    .onClick(() => {
        // 点击事件
    })

// 按钮类型
Button('默认按钮', { type: ButtonType.Capsule })
Button('次要按钮', { type: ButtonType.Normal })
Button('文字按钮', { type: ButtonType.Text })
Button('描边按钮', { type: ButtonType.Stroked })

2.4 Divider — 分隔线

typescript
Divider()
    .strokeWidth(1px)
    .color(Color.Gray)
    .margin({ left: 16, right: 16 })

3. 输入组件

3.1 TextInput — 单行输入框

typescript
TextInput({ placeholder: '请输入用户名' })
    .width('100%')
    .height(48vp)
    .fontSize(16fp)
    .borderRadius(8vp)
    .backgroundColor(Color.White)
    .padding(12vp)
    .onChange((value: string) => {
        // 输入变化回调
        this.username = value
    })
    .type(InputType.Text)  // Text/Email/Number/Password
    .maxLength(20)
type说明
InputType.Text普通文本
InputType.Email邮箱键盘
InputType.Number数字键盘
InputType.Password密码模式
InputType.Phone电话键盘

3.2 TextArea — 多行文本框

typescript
TextArea({ placeholder: '请输入内容' })
    .width('100%')
    .height(150vp)
    .fontSize(16fp)
    .borderRadius(8vp)
    .backgroundColor(Color.White)
    .padding(12vp)
    .onChange((value: string) => {
        this.content = value
    })
    .maxLength(500)

3.3 Checkbox — 复选框

typescript
Row() {
    Checkbox({ group: 'agree' })
        .onChange((isChecked: boolean) => {
            this.agreed = isChecked
        })
    Text('同意用户协议')
        .fontSize(14fp)
        .margin({ left: 8 })
}

3.4 Switch — 开关

typescript
Row() {
    Text('开启通知')
        .fontSize(16fp)
    Switch({ type: SwitchType.CIRCLE })
        .selected(this.notificationEnabled)
        .onChange((value: boolean) => {
            this.notificationEnabled = value
        })
}
.alignItems(VerticalAlign.Center)

3.5 Slider — 滑块

typescript
Slider({
    min: 0,
    max: 100,
    value: 50,
    step: 1
})
.width('80%')
.blockSize(20)
.blockColor(Color.Blue)
.activeColor(Color.Blue)
.normalColor(Color.Gray)
.onChange((value: number) => {
    this.volume = value
})

4. 列表组件

4.1 List — 列表

typescript
List() {
    ListItem() {
        Text('Item 1')
    }
    ListItem() {
        Text('Item 2')
    }
    ListItem() {
        Text('Item 3')
    }
}
.width('100%')
.height('100%')
.edgePadding({ left: 16, right: 16, top: 10, bottom: 10 })

4.2 LazyForEach + List — 长列表(推荐)

typescript
@Entry
@Component
struct Index {
    @State items: string[] = []
    private myDataSource: MyDataSource = new MyDataSource()

    build() {
        Column() {
            List() {
                LazyForEach(this.myDataSource, (item: string) => {
                    ListItem() {
                        Text(item)
                            .fontSize(16fp)
                            .padding(16vp)
                            .backgroundColor(Color.White)
                            .margin({ bottom: 1 })
                    }
                })
            }
            .width('100%')
            .layoutWeight(1)
            .edgePadding({ top: 10, bottom: 10 })
        }
        .width('100%')
        .height('100%')
    }
}

// IDataSource 实现
class MyDataSource implements IDataSource {
    private mData: string[] = []
    private listener: DataChangeListener | undefined

    refreshData(): void {
        // 模拟数据
        this.mData = Array.from({ length: 100 }, (_, i) => `Item ${i}`)
        if (this.listener) {
            this.listener.onDataReload(this)
        }
    }

    getData(index: number): string {
        return this.mData[index]
    }

    getCount(): number {
        return this.mData.length
    }

    registerDataChangeListener(listener: DataChangeListener): void {
        this.listener = listener
    }

    unregisterDataChangeListener(listener: DataChangeListener): void {
        this.listener = undefined
    }
}

4.3 Grid — 网格列表

typescript
Grid() {
    ForEach(this.gridItems, (item: any) => {
        GridItem() {
            Column() {
                Image(item.icon)
                    .width(60vp)
                    .height(60vp)
                Text(item.name)
                    .fontSize(12fp)
                    .margin({ top: 8 })
            }
        }
    }, (item: any) => item.id)
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.gap(12)
.width('100%')

4.4 Swiper — 轮播图

typescript
Swiper() {
    ForEach(this.banners, (banner: Banner) => {
        Image(banner.url)
            .width('100%')
            .height(200vp)
            .objectFit(ImageFit.Cover)
    }, (banner: Banner) => banner.id)
}
.index(this.currentIndex)
.indicator(true)
.indicatorWidth(60vp)
.indicatorHeight(4vp)
.indicatorBorderRadius(2vp)
.indicatorMargin({ bottom: 10 })
.indicatorStyle(SwiperIndicatorStyle.ROUND)
.interval(3000)
.autoPlay(true)
.loop(true)
.onChange((index: number) => {
    this.currentIndex = index
})

5. 滚动组件

5.1 Scroll — 滚动容器

typescript
Scroll() {
    Column() {
        ForEach(this.items, (item: Item) => {
            ListItem() {
                Text(item.title)
                    .padding(16vp)
            }
        })
    }
}
.width('100%')
.height('100%')
.scrollBar(BarState.Off)  // 隐藏滚动条
.edgePadding({ top: 10, bottom: 10 })
.onScrollFrame((offset: number) => {
    // 滚动帧回调
})
.scroller(this.scroller)

5.2 Scroll 的属性

属性说明
scrollBar滚动条状态(On/Off/Always)
edgePadding边缘间距
vertical是否垂直滚动(默认 true)
showScrollbar显示滚动指示器
scrollerScrollScroller 实例(编程式滚动)

6. 弹窗组件

6.1 Dialog — 系统弹窗

typescript
@Entry
@Component
struct Index {
    private controller: DialogController = new DialogController({
        autoCancel: true,
        alignment: DialogAlignment.Center,
        offset: { dx: 0, dy: 0 }
    })

    build() {
        Column() {
            Button('打开弹窗')
                .onClick(() => {
                    this.controller.open(
                        () => {
                            Text('确认删除吗?')
                                .fontSize(18fp)
                        },
                        [
                            { action: '取消', actionChild: () => this.controller.close() },
                            { action: '删除', actionChild: () => { /* 删除逻辑 */ ; this.controller.close() } }
                        ],
                        { cancel: () => this.controller.close() }
                    )
                })
        }
    }
}

6.2 CustomDialogController — 自定义弹窗

typescript
@CustomDialog
struct ConfirmDialog {
    controller: CustomDialogController
    title: string = '提示'
    content: string = '确定吗?'

    build() {
        Column() {
            Text(this.title)
                .fontSize(20fp)
                .fontWeight(FontWeight.Bold)
                .margin({ bottom: 16 })

            Text(this.content)
                .fontSize(16fp)
                .margin({ bottom: 24 })

            Row() {
                Button('取消')
                    .width('48%')
                    .onClick(() => this.controller.close())
                Button('确定')
                    .width('48%')
                    .onClick(() => this.controller.close())
            }
        }
        .width('80%')
        .padding(24)
    }
}

@Entry
@Component
struct Index {
    private dialogController = new CustomDialogController({
        builder: ConfirmDialog({ title: '提示', content: '确定删除吗?' }),
        alignment: DialogAlignment.Center,
        customPanelState: CustomPanelState.POPUP
    })

    build() {
        Column() {
            Button('打开弹窗')
                .onClick(() => this.dialogController.open())
        }
    }
}

7. 导航组件

7.1 Navigation — 页面导航

typescript
@Entry
@Component
struct Index {
    private navPathStack: NavPathStack = new NavPathStack()

    build() {
        Navigation(this.navPathStack) {
            NavDestination() {
                Text('首页')
                    .fontSize(32fp)
                    .fontWeight(FontWeight.Bold)
            }
            .title('首页')

            NavDestination({ type: 'detail' }) {
                Text('详情页')
                    .fontSize(24fp)
            }
            .title('详情')
        }
        .width('100%')
        .height('100%')
    }
}

8. 组件属性速查表

属性类别常用属性
几何属性width/height/minWidth/maxWidth/minHeight/maxHeight
边距margin/padding
位置position(left/top/right/bottom)
背景backgroundColor/backgroundImage
边框border(width/color/radius)
圆角borderRadius/clip
阴影boxShadow
文字fontSize/fontColor/fontWeight/textAlign/maxLines
动画animation
可见性visibility
点击onClick
长按onLongClick

9. 面试高频考点

Q1: 鸿蒙常用的内置组件有哪些?

回答:基础(Text/Image/Button/Divider)、输入(TextInput/TextArea)、列表(List/Grid/Swiper)、滚动(Scroll)、弹窗(Dialog/CustomDialog)、导航(Navigation)等。

Q2: LazyForEach 和 ForEach 的区别?

回答:ForEach 全量渲染,适合少量数据;LazyForEach 按需渲染,配合 IDataSource 使用,长列表必用。

Q3: Swiper 的关键属性?

回答:index、indicator、interval、autoPlay、loop、onChange。用于轮播图的索引、指示器、自动播放和循环。


🐱 小猫提示:内置组件记住核心分组:基础/输入/列表/滚动/弹窗/导航。面试时列举 2-3 个代表组件即可。