探索HarmonyOS NEXT的强大UI组件,打造精美多媒体应用
HarmonyOS NEXT作为华为自主研发的操作系统,为开发者提供了一套丰富而强大的UI组件库。本文将详细介绍四种常用多媒体组件的使用方法:Image图片显示、Video视频播放、Swiper轮播图和ArcSwiper弧形轮播图,帮助您快速提升应用开发效率。
1. 显示图片(Image组件)
Image组件是HarmonyOS中用于显示图片的核心组件,支持多种图片格式和源类型。
基本用法
typescript
Image('images/panda.jpg') .width(100) .height(100)
支持的数据源类型
Image组件支持多种数据源:17
本地资源:存放在ets文件夹下的资源
typescript
Image('images/view.jpg').width(200)
Resource资源:通过$r资源接口读取
typescript
Image($r('app.media.icon'))
网络资源:需要申请网络权限
typescript
Image('https://www.example.com/example.JPG')
媒体库资源:通过file://前缀访问
typescript
Image('file://media/Photos/5').width(200)
Base64资源:直接使用base64编码数据
typescript
Image('data:image/png;base64,...')
PixelMap:图片解码后的像素图
typescript
@State image: PixelMap | undefined = undefined // ...处理后 Image(this.image).width(100).height(100)
常用属性配置
Image组件提供了一系列属性用于控制图片显示效果:1
typescript
Image($r('app.media.cat')) .width(100) .height(200) .objectFit(ImageFit.Fill) // 设置缩放类型 .fillColor(Color.Blue) // 设置SVG图片的绘制颜色
objectFit 支持多种枚举值:1
属性值 | 说明 |
---|---|
ImageFit.Contain | 保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内 |
ImageFit.Cover | 保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界 |
ImageFit.Auto | 自适应显示 |
ImageFit.Fill | 不保持宽高比进行放大缩小,使得图片充满显示边界 |
ImageFit.ScaleDown | 保持宽高比显示,图片缩小或者保持不变 |
ImageFit.None | 保持原有尺寸显示 |
网络图片权限申请
使用网络图片需要在module.json5文件中声明权限:1
json
{ "module": { "requestPermissions": [ { "name": "ohos.permission.INTERNET" } ] } }
2. 视频播放(Video组件)
Video组件用于在应用中播放视频内容,支持多种视频源和控制方式。
创建Video组件
Video组件通过调用接口创建:58
typescript
Video({ src: this.videoSrc, previewUri: this.previewUris, controller: this.controller })
加载视频资源
Video组件支持多种视频源:5
本地视频资源:
typescript
private innerResource: Resource = $rawfile('videoTest.mp4')
网络视频资源:
typescript
private videoUrl = 'https://example.com/video.mp4'
Data Ability提供的路径:
typescript
private videoSrc: string = 'dataability://device_id/com.domainname.dataability.videodata/video/10'
沙箱路径视频:
typescript
private videoSrc: string = 'file:///data/storage/el2/base/haps/entry/files/show.mp4'
视频格式支持
Video组件支持的视频格式包括:mp4、mkv、webm、TS8。
完整示例代码
typescript
import router from '@ohos.router'; @Entry @Component struct VideoPage { private TAG: string = 'VideoPage' private netVideoController: VideoController = new VideoController() private videoUrl: string = 'https://example.com/video.mp4' @State currentTime: number = 0 @State durationTime: number = 0 build() { Column() { Video({ src: this.videoUrl, controller: this.netVideoController }) .muted(false) // 设置是否静音 .controls(true) // 设置是否显示默认控制条 .autoPlay(false) // 设置是否自动播放 .loop(false) // 设置是否循环播放 .objectFit(ImageFit.Contain) // 设置视频适配模式 .width('90%') .height(200) .onPrepared((event) => { // 准备完成回调 if (event) { this.durationTime = event.duration } }) .onUpdate((event) => { // 播放进度更新回调 if (event) { this.currentTime = event.time } }) .onFinish(() => { // 播放完成回调 console.info(`${this.TAG} onFinish `) }) .onError(() => { // 播放错误回调 console.info(`${this.TAG} onError `) }) // 自定义进度条 Row() { Text(`${this.currentTime}s`) Slider({ value: this.currentTime, min: 0, max: this.durationTime }) .onChange((value: number, mode: SliderChangeMode) => { this.netVideoController.setCurrentTime(value) }) .width("80%") Text(`${this.durationTime}s`) } .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.Center) .opacity(0.8) .width("90%") Button('开始播放') .onClick(() => { this.netVideoController.start() }) .width('80%') } } }
权限申请
视频播放需要申请相应权限,在module.json5文件中添加:8
json
{ "module": { "requestPermissions": [ { "name": "ohos.permission.INTERNET", "usedScene": { "when": "always" } }, { "name": "ohos.permission.MODIFY_AUDIO_SETTINGS", "usedScene": { "when": "always" } }, { "name": "ohos.permission.READ_MEDIA", "usedScene": { "when": "always" } } ] } }
3. 创建轮播(Swiper组件)
Swiper组件提供子组件滑动轮播显示的能力,常用于创建图片轮播、横幅广告等效果。
基本用法
typescript
// 创建控制器 private swiperController: SwiperController = new SwiperController() // 初始化轮播数据 private bannerArray: Array<Resource> = [ $r("app.media.banner_1"), $r("app.media.banner_2"), $r("app.media.banner_3") ] build() { Swiper(this.swiperController) { ForEach(this.bannerArray, (item: Resource) => { Image(item) .width('100%') .height(150) .objectFit(ImageFit.Cover) }, (item: Resource) => JSON.stringify(item)) } .vertical(false) // 是否垂直方向 .index(0) // 默认显示第几个组件 .cachedCount(1) // 预加载子组件个数 .autoPlay(true) // 是否自动轮播 .loop(true) // 是否循环轮播 .interval(4000) // 轮播间隔,单位毫秒 .duration(1000) // 轮播时长,单位毫秒 .indicator(true) // 是否显示指示器 }
SwiperController控制器
SwiperController提供了一些控制方法:9
showNext()
: 翻到下一页showPrevious()
: 翻到上一页changeIndex()
: 翻到指定位置的页面
自定义指示器
可以使用自定义指示器替代默认指示器:6
typescript
@State currentIndex: number = 0 build() { Column() { Swiper(this.swiperController) { // ...轮播内容 } .indicator(false) // 关闭默认指示器 .onChange((index: number) => { this.currentIndex = index // 监听页面变化 }) // 自定义指示器 Row({ space: 5 }) { ForEach(this.bannerArray, (item: Resource, index: number) => { Stack({ alignContent: Alignment.Start }) { Row() .zIndex(1) .width(this.currentIndex >= index ? '100%' : '0') .height(2) .borderRadius(2) .backgroundColor(Color.Blue) } .width('100%') .height(2) .borderRadius(2) .backgroundColor(this.currentIndex >= index ? Color.Blue : Color.Grey) .layoutWeight(1) }, (item: Resource) => JSON.stringify(item)) } .width('50%') .height(50) } }
LazyForEach懒加载
对于大量数据的轮播,建议使用LazyForEach进行懒加载:6
typescript
// 实现IDataSource接口 export class LazyData<T> implements IDataSource { private listeners: DataChangeListener[] = [] private array: Array<T> = [] totalCount(): number { return this.array.length } getData(index: number): T { return this.array[index] } registerDataChangeListener(listener: DataChangeListener): void { if (this.listeners.indexOf(listener) < 0) { this.listeners.push(listener) } } unregisterDataChangeListener(listener: DataChangeListener): void { const index = this.listeners.indexOf(listener) if (index >= 0) { this.listeners.splice(index, 1) } } push(data: T) { this.array.push(data) } } // 使用LazyForEach @State data: LazyData<PhotoData> = new LazyData() Swiper(this.swiperController) { LazyForEach(this.data, (item: PhotoData, index: number) => { Image($r(`app.media.` + item.id)) .width('100%') .height('30%') }, (item: PhotoData) => JSON.stringify(item)) }
4. 创建弧形轮播(ArcSwiper组件)
ArcSwiper是弧形滑块视图容器,提供子组件滑动轮播显示的能力,适用于圆形或弧形显示设备的特殊需求。
基本用法
typescript
import { ArcSwiper, ArcSwiperAttribute, ArcDotIndicator, ArcDirection, ArcSwiperController } from '@kit.ArkUI'; // 创建控制器 private arcSwiperController: ArcSwiperController = new ArcSwiperController() build() { ArcSwiper(this.arcSwiperController) { // 子组件内容 ForEach(this.bannerArray, (item: Resource) => { Image(item) .width(100) .height(100) }) } .index(0) // 当前显示的子组件索引值 .indicator(true) // 启用弧形圆点指示器 .duration(400) // 子组件切换的动画时长 .vertical(false) // 是否为纵向滑动 .disableSwipe(false) // 是否禁用滑动切换功能 .effectMode(EdgeEffect.Spring) // 边缘滑动效果 }
ArcSwiperController控制器
ArcSwiperController提供弧形轮播的控制方法:4
typescript
// 翻至下一页,带动效切换过程 this.arcSwiperController.showNext() // 翻至上一页,带动效切换过程 this.arcSwiperController.showPrevious() // 停止播放动画 this.arcSwiperController.finishAnimation(() => { // 动画结束回调 })
指示器定制
可以定制弧形圆点指示器的样式:4
typescript
ArcSwiper(this.arcSwiperController) { // ...子组件 } .indicator( new ArcDotIndicator() .color(Color.Gray) // 默认颜色 .selectedColor(Color.Blue) // 选中颜色 .size(6) // 指示器大小 .selectedSize(8) // 选中指示器大小 )
高级属性配置
ArcSwiper还提供了一些高级配置属性:4
typescript
ArcSwiper(this.arcSwiperController) { // ...子组件 } .digitalCrownSensitivity(CrownSensitivity.MEDIUM) // 设置旋转表冠的灵敏度 .disableTransitionAnimation(false) // 是否关闭特殊动效效果
总结
HarmonyOS NEXT提供了丰富多样的多媒体组件,使开发者能够轻松创建出功能强大、视觉效果出色的应用:
Image组件支持多种图片格式和数据源,满足各种场景下的图片显示需求。
Video组件提供了完善的视频播放能力,支持本地和网络视频源,并具备完善的播放控制功能。
Swiper组件可以创建平滑的轮播效果,支持自动播放、循环播放等特性,适合图片展示和横幅广告。
ArcSwiper组件专为弧形屏幕设备设计,提供独特的弧形轮播体验,扩展了应用的表现形式。
通过灵活运用这些组件,开发者可以为用户创造更加丰富、生动的视觉体验,提升应用的整体质量和吸引力。