探索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组件专为弧形屏幕设备设计,提供独特的弧形轮播体验,扩展了应用的表现形式。
通过灵活运用这些组件,开发者可以为用户创造更加丰富、生动的视觉体验,提升应用的整体质量和吸引力。