HarmonyOS 鸿蒙Next求助:时间进度条怎么搞?
HarmonyOS 鸿蒙Next求助:时间进度条怎么搞?
本人目前想做一个时间进度条(刻度条)开始时间是0:00,结束时间是24:00,小时和小时之间还有刻度
时间进度条的特性:
- 可以滑动,滑动到哪里,中间的紫色显示滑动到的时间。精确到秒
- 时间轴可以放大缩小:小时和小时之间6个格子(1格子代表10分钟),根据收拾捏合放大缩小
放大:原来默认小时为单位(1刻度代表10分钟),放大后10分钟为单位(里面1刻度代表1分钟),继续放大到1分钟为单位(1刻度代表1秒钟)
这种需求怎么搞?我没有做过相关,有大佬可以指一下路吗?或者有相关Demo可以提供一下,感激不尽
更多关于HarmonyOS 鸿蒙Next求助:时间进度条怎么搞?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
- 实现时间卡尺模型:
if(this.divisorMode == TimeBarViewModel.MODE_HOUR) {
//小时模式
//中心点距离左边所占用的时长
this.middleLineDuration = Math.floor((this.viewWidth / 2) * (TimeBarViewModel.TEN_MINUTE / this.divisorWidth))
//计算屏幕最左边的时间
this.leftTime = this.middleLineMillis - this.middleLineDuration
//计算左边第一个刻度线的位置
//由原来Java代码中的Math.ceil改成Math.floor,解决分钟模式下左侧不绘制刻度问题
minuteNum = Math.floor(this.leftTime / TimeBarViewModel.TEN_MINUTE)
xPosition =
((minuteNum * TimeBarViewModel.TEN_MINUTE) - this.leftTime) * (this.divisorWidth / TimeBarViewModel.TEN_MINUTE)
} else if (this.divisorMode == TimeBarViewModel.MODE_MINUTE) {
//分钟模式
...
}
//计算左边第一个刻度线是今天的第多少个分钟数
for (let i = 0; i < scaleNum; i++) {
if (this.divisorMode == TimeBarViewModel.MODE_HOUR) {
//小时级别的画法
if (minuteNum % 6 == 0) { //大刻度
//画上面的大刻度
this.scalePaint!.beginPath()
this.scalePaint!.moveTo(xPosition + i * this.divisorWidth, this.viewHeight - this.scaleHeight * 2)
this.scalePaint!.lineTo(xPosition + i * this.divisorWidth, this.viewHeight)
this.scalePaint!.stroke()
let hourMinute = this.getHourMinute(minuteNum)
let timeStrWidth = this.scalePaint!.measureText(hourMinute).width
this.timeStrHeight = this.scalePaint!.measureText(hourMinute).height
//画出时间文字
this.scalePaint!.fillText(hourMinute, xPosition + i * this.divisorWidth - timeStrWidth / 2,
this.viewHeight - (this.scaleHeight * 2 + this.timeStrHeight))
} else {
//画上面的小刻度
this.scalePaint!.beginPath()
this.scalePaint!.moveTo(xPosition + i * this.divisorWidth, this.viewHeight - this.scaleHeight)
this.scalePaint!.lineTo(xPosition + i * this.divisorWidth, this.viewHeight)
this.scalePaint!.stroke()
}
} else if (this.divisorMode == TimeBarViewModel.MODE_MINUTE) {
//分钟级别的画法
...
}
//每一格刻度代表10分钟
if (this.divisorMode == TimeBarViewModel.MODE_HOUR) {
minuteNum++;
} else if(this.divisorMode == TimeBarViewModel.MODE_MINUTE) {
secondNum++;
}
在onPanActionEnd手势动作函数钟,通过middleLineMillis和videoCaliperInfo实现视频进度同步
// 视频同步
this.videoInfoList.forEach((video, index) => {
video.isPlayed = this.hasVideoPlayed(index);
if(video.isPlayed) {
this.controller.setCurrentTime(Math.floor((this.middleLineMillis - video.caliperBeginStamp)/1000))
}
})
完整代码:
import { RecordSegment } from './RecordSegment'
import { TimeBarView } from './TimeBarView'
import { TimeBarViewModel } from './TimeBarViewModel';
import List from '@ohos.util.List';
import dayJs from 'dayjs'
import { VideoCaliperInfo } from '../utils/VideoCaliperInfo';
@Entry
@Component
struct Index {
@State private model: TimeBarViewModel = new TimeBarViewModel();
@State currentTime: number = 0
aboutToAppear(): void {
let videos: List<VideoCaliperInfo> = new List();
let beginTime1: number = this.model.yyyy_MM_dd_T_HH_mm_SSSZToCalendar('2024-05-13T23:37:16.000+08:00').getTime();
let beginTime2: number = this.model.yyyy_MM_dd_T_HH_mm_SSSZToCalendar('2024-05-14T03:10:24.000+08:00').getTime();
let endTime1: number = this.model.yyyy_MM_dd_T_HH_mm_SSSZToCalendar('2024-05-13T23:37:29.000+08:00').getTime();
let endTime2: number = this.model.yyyy_MM_dd_T_HH_mm_SSSZToCalendar('2024-05-14T03:10:58.000+08:00').getTime();
let videoOptions1: VideoOptions = { src:$rawfile('1.mp4'), controller:this.model.controller }
let videoOptions2: VideoOptions = { src:$rawfile('3.mp4'), controller:this.model.controller }
let videoCaliperInfo1: VideoCaliperInfo = new VideoCaliperInfo(videoOptions1, beginTime1, endTime1, false)
let videoCaliperInfo2: VideoCaliperInfo = new VideoCaliperInfo(videoOptions2, beginTime2, endTime2, false)
videos.add(videoCaliperInfo1);
videos.add(videoCaliperInfo2);
let fileInfoList: List<RecordSegment> = new List();
let recordSegment1 = new RecordSegment()
recordSegment1.recordType = 0
recordSegment1.beginTime = '2024-05-13T23:37:16.000+08:00'
recordSegment1.endTime = '2024-05-13T23:37:29.000+08:00'
fileInfoList.add(recordSegment1)
let recordSegment2 = new RecordSegment()
recordSegment2.beginTime = '2024-05-14T03:10:24.000+08:00'
recordSegment2.endTime = '2024-05-14T03:10:58.000+08:00'
fileInfoList.add(recordSegment2)
this.model.addFileInfoList(fileInfoList)
this.model.addVideoInfoList(videos)
}
build() {
Column() {
Column(){
Text('录像时间卡尺')
.fontSize('30fp')
.fontWeight(700)
.margin({ top: '64vp' })
}
.width('100%')
.height('20%')
.margin({bottom:40})
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Start)
Stack(){
ForEach(this.model.getVideosList(), (video: VideoCaliperInfo, index: number) => {
if(video.isPlayed) {
Video(video.videoOption)
.controls(false)
.autoPlay(true)
}
})
}
.margin({bottom:20})
.height('30%')
Column(){
Text(dayJs(new Date(this.model.middleLineMillis)).format('YYYY-MM-DD HH:mm:ss'))
.padding(15)
TimeBarView({ model: this.model })
}
.height('30%')
}
.width('100%')
.height('100%')
}
}
更多关于HarmonyOS 鸿蒙Next求助:时间进度条怎么搞?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
是的 和我发现的Demo代码一样 谢谢,
我来做的话会自定义组件 结合手势自己写一套 看楼主是怎么实现的
楼主这个是想做一个拖动获取或者设置时间的UI吗,成功了的话 我也参考学习一下
你不准学了,快去振刀,
你不准学了,快去振刀,
学习鸿蒙,
时间刻度轴
- 开始时间: 2023-01-01
- 结束时间: 2023-12-31
事件1
- 日期: 2023-03-15
事件2
- 日期: 2023-06-20
事件3
- 日期: 2023-09-10
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
可以试试用scroll
组件,横向,然后自定义滑块样式,或者里面元素滚动,
项目名称
- 项目类型: 网站
- 状态: 进行中
- 开始日期: 2023-09-01
- 结束日期: 2023-12-31
- 描述: 这是一个示例项目,用于展示如何将HTML内容转换为Markdown格式。
在HarmonyOS Next中,使用<Progress>
组件创建时间进度条。设置progress
属性为当前进度值(0-100),style
属性可自定义样式。示例代码:
<Progress
progress="30"
style="width: 300px; height: 6px;"
class="my-progress"/>
通过$element
获取组件对象,调用setProgress()
动态更新进度值。支持线性/环形样式,通过type
属性切换。
在HarmonyOS Next中实现时间进度条,可以使用Slider
组件结合自定义绘制来实现。以下是关键实现思路:
-
使用
Slider
作为基础控件,设置minValue=0,maxValue=86400(24小时对应的秒数) -
自定义刻度绘制:
@Component
struct TimeSlider {
@State currentTime: number = 0
@State scaleLevel: number = 1 // 缩放级别
build() {
Slider({
value: this.currentTime,
min: 0,
max: 86400,
step: this.getStep(),
style: SliderStyle.OutSet
})
.onChange(value => {
this.currentTime = value
})
.trackThickness(20)
.selectedColor(Color.Purple)
.showSteps(true)
.showTips(true)
}
// 根据缩放级别返回步长
private getStep(): number {
switch(this.scaleLevel) {
case 1: return 600 // 10分钟
case 2: return 60 // 1分钟
case 3: return 1 // 1秒
default: return 600
}
}
}
- 添加捏合手势识别:
.gesture(
PinchGesture()
.onActionStart(() => {
// 处理缩放开始
})
.onActionUpdate((event: PinchGestureEvent) => {
if(event.scale > 1.5) {
this.scaleLevel = Math.min(this.scaleLevel + 1, 3)
} else if(event.scale < 0.5) {
this.scaleLevel = Math.max(this.scaleLevel - 1, 1)
}
})
)
- 时间显示可以使用Text组件实时更新:
Text(this.formatTime(this.currentTime))
.fontSize(20)
.fontColor(Color.Purple)
private formatTime(seconds: number): string {
// 秒数转HH:mm:ss格式
}
注意:完整实现还需要处理手势冲突、刻度标签绘制等细节。建议参考HarmonyOS的Slider和Canvas组件文档进行扩展开发。