场景说明
应用开发中经常需要给同一个组件划分不同的触摸热区,并且不同热区触发的操作也不同,比如阅读应用通常包含左右两个触摸热区,用户触摸左侧触发向后翻页,触摸右侧触发向前翻页;同样的,视频应用中,长按视频播放器的左侧触发快退播放,长按右侧触发快进播放等等。 当前OpenHarmony提供的热区设置属性(responseRegion)只能在不同的触摸热区中触发相同的事件,那么如何实现不同热区不同事件呢,本例即以上述视频播放场景为例进行说明。
效果呈现
效果说明:开始时视频以正常速度播放,播放到5秒时,长按播放器右侧触发快进播放,播放到14秒时长按播放器左侧触发快退播放。
环境要求
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
- IDE: DevEco Studio 4.0 Release
- SDK: Ohos_sdk_public 4.0.10.13 (APIVersion 10 Release)
实现思路
几乎组件的所有触摸事件都会返回event,通过返回的event可以获取到触摸点的坐标位置,那么就可以根据坐标位置为不同的组件区域添加不同的交互动作。如图:假设有一个长度为200vp的组件,我们希望点击组件的左侧时触发事件A,点击组件的右侧时触发事件B,那么就可以通过触摸点的坐标来判断,当触摸点的x坐标<=100时,触发事件A,反之触发事件B。
本例即采用上述思路为Video组件的左右两侧添加不同的交互动作。从而实现长按视频播放器的左侧触发后退播放,长按右侧触发快进播放。
开发步骤
本例详细开发步骤如下,开发步骤中仅展示相关步骤代码,全量代码请参考完整代码章节的内容。
1.通过Video组件创建视频播放器,并添加触摸手势,通过触摸控制视频的播放、暂停。
@Component
export struct VideoPlayer{
//...
private isPlaying:boolean = true
private updateTime: number
private videoController:VideoController = new VideoController()
build(){
// 添加视频组件
Video({src:this.videoSrc, controller:this.videoController, previewUri:this.videoPreviewer,currentProgressRate:this.playRate})
//...
// 获取当前进度条的时间点
.onUpdate((e)=>{
this.updateTime = e.time
})
.gesture(
// 添加触摸手势
TapGesture({count:1})
.onAction((event:GestureEvent)=>{
if (this.isPlaying){
// 触摸触发播放
this.videoController.start()
this.isPlaying = !this.isPlaying
} else {
// 再次触摸触发暂停
this.videoController.pause()
this.isPlaying =!this.isPlaying
}
})
)
}
}
2.为Video组件添加长按手势,通过长按手势触发播放的快退和快进动作。由于触摸手势和长按手势需要互斥,即一次只能触发一种手势,所以通过GestureGroup来实现手势的互斥。
.gesture(
// 通过GestureGroup的GestureMode.Exclusive参数控制手势互斥
GestureGroup(GestureMode.Exclusive,
// 添加触摸手势
TapGesture({count:1})
.onAction((event:GestureEvent)=>{
if (this.isPlaying){
// 触摸触发播放
this.videoController.start()
this.isPlaying = !this.isPlaying
} else {
// 再次触摸触发暂停
this.videoController.pause()
this.isPlaying =!this.isPlaying
}
}),
// 添加长按手势
LongPressGesture({repeat:true})
// 长按时触发快进或快退
.onAction((event)=>{
//添加快进和快退的逻辑,通过event获取手势坐标进行判断。
})
// 长按结束后播放速度回归正常
.onActionEnd(()=>{
// 添加回归正常播放的逻辑
})
)
)
3.补充长按手势中的业务逻辑:通过event获取到触摸点的x坐标:localX,当localX>=200时,说明触摸点在组件的右侧,触发快进播放;当localX<200时,说明触摸点在左侧,触发快退播放。当触摸停止时,回归正常播放速度。
// 添加长按手势
LongPressGesture({repeat:true})
// 长按时触发快进或快退
.onAction((event)=>{
// 获取到触摸点x坐标localX,当localX>=200时,说明触摸点在组件的右侧,触发快进播放
if (event.fingerList[0].localX>=200){
// 播放速度变为2倍速
this.playRate = PlaybackSpeed.Speed_Forward_2_00_X
}
// 当localX<200时,说明触摸点在左侧,触发快退播放
if (event.fingerList[0].localX<200){
if (this.intervalCount===0){
// 通过进度时间减小来达到快退的目的,通过setInterval来控制后退的速度,否则会连续触发后退,瞬间后退到播放起点
this.seekBack = setInterval(()=>{
this.updateTime -= 1
this.videoController.setCurrentTime(this.updateTime)
},500)
}
this.intervalCount = 1
}
})
// 长按结束后播放速度回归正常
.onActionEnd(()=>{
// 播放回归到1倍速
this.playRate = PlaybackSpeed.Speed_Forward_1_00_X
// 清空计时器
clearInterval(this.seekBack)
this.intervalCount = 0
})
完整代码
本例完整代码如下:
说明: 本例中使用的视频等资源需要替换为开发者自己的资源
@Entry
@Component
export struct VideoPlayer{
private videoSrc:Resource = $rawfile('video_1.mp4')
private isPlaying:boolean = true
private updateTime: number = 0
private videoPreviewer:Resource = $r('app.media.wandering_previewer')
private videoController:VideoController = new VideoController()
@State playRate:number = 1
private seekBack:number = 0
private intervalCount:number = 0
build(){
Column(){
// 添加视频组件
Video({src:this.videoSrc, controller:this.videoController, previewUri:this.videoPreviewer,currentProgressRate:this.playRate})
.width('100%')
.height('30%')
.backgroundColor('#fffff0')
.controls(true)
.objectFit(ImageFit.Contain)
// 获取当前进度条的时间点
.onUpdate((e)=>{
this.updateTime = e.time
})
.gesture(
// 通过GestureGroup的GestureMode.Exclusive参数控制手势互斥
GestureGroup(GestureMode.Exclusive,
// 添加触摸手势
TapGesture({count:1})
.onAction((event:GestureEvent)=>{
if (this.isPlaying){
// 触摸触发播放
this.videoController.start()
this.isPlaying = !this.isPlaying
} else {
// 再次触摸触发暂停
this.videoController.pause()
this.isPlaying =!this.isPlaying
}
}),
// 添加长按手势
LongPressGesture({repeat:true})
// 长按时触发快进或快退
.onAction((event)=>{
// 获取到触摸点x坐标localX,当localX>=200时,说明触摸点在组件的右侧,触发快进播放
if (event.fingerList[0].localX>=200){
// 播放速度变为2倍速
this.playRate = PlaybackSpeed.Speed_Forward_2_00_X
}
// 当localX<200时,说明触摸点在左侧,触发快退播放
if (event.fingerList[0].localX<200){
if (this.intervalCount===0){
// 通过进度时间减小来达到快退的目的,通过setInterval来控制后退的速度,否则会连续触发后退,瞬间后退到播放起点
this.seekBack = setInterval(()=>{
this.updateTime -= 1
this.videoController.setCurrentTime(this.updateTime)
},500)
}
this.intervalCount = 1
}
})
// 长按结束后播放速度回归正常
.onActionEnd(()=>{
// 播放回归到1倍速
this.playRate = PlaybackSpeed.Speed_Forward_1_00_X
// 清空计时器
clearInterval(this.seekBack)
this.intervalCount = 0
})
)
)
}
.height('100%')
.width('100%')
}
}
我这边特意整理了《鸿蒙语法ArkTS、TypeScript、ArkUI、实战开发视频教程》以及《鸿蒙生态应用开发白皮书V2.0PDF》《鸿蒙开发学习手册》(共计890页)鸿蒙开发资料等…希望对大家有所帮助:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
OpenHarmony APP开发教程步骤:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
鸿蒙生态应用开发白皮书V2.0PDF:https://docs.qq.com/doc/DZVVkRGRUd3pHSnFG
应用开发中级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
应用开发中高级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
南北双向高工技能基础:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
全网首发-工业级 南向设备开发就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
《鸿蒙开发学习手册》:
如何快速入门:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.基本概念
2.构建第一个ArkTS应用
3.……
开发基础知识:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……
基于ArkTS 开发:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……