Foreword
this article is based on Api12
some time ago, a small partner said a need to realize the function of editing an audio track. However, he was busy with his work and did not have time to do it. I am very sorry. Now that I have a little leisure time, I have started to realize it. I hope I can help friends who have this need.
Since it is a function of editing and interception, audio and video are the same, except that the tracks and progress are different, but the dragging sliders are similar. Apart from the common use of audio and video, scenes with two-way sliding requirements can also be met.
At present, the simple implementation effect is as follows, and various styles such as color can be dynamically set.
The general content of this article is as follows:
1. How to realize such a double slider component
2. Overview of code implementation
3, open source address and function use
4. Relevant summary
first, how to achieve such a double sliding component
the first is the UI view, which can be divided into three or two layers. If there are three layers, the bottom track is one layer, the border is one layer, and the two sliders are one layer. If there are two layers, the bottom track and border are one layer, and the upper two sliders are one layer.
The most important thing is the gesture of the two sliders. In addition to moving with the gesture, the slider should also record the position of the last gesture lift to facilitate continuous sliding. It is recommended to use onTouch event instead of gesture event here, because onTouch records coordinates more accurately and can move components smoothly.
It should be noted that the left and right sliding blocks need to be set with the maximum and minimum valves, that is to say, the left cannot slide beyond the right position, and the right cannot slide beyond the left position, and of course, cannot exceed the left and right positions of the track.
Since the sliding display is coordinates, the final percentage needs to be calculated using the coordinates and the overall width of the track, which needs to be noted.
II. Overview of Code Implementation
in the code here, I AM also divided into three layers, the bottom track, the Middle Border and the upper slider according to the first one.
We try not to use my default track, because the default is only a simple implementation of the audio track, and does not draw according to the frequency of video or audio, so it does not meet the actual development needs, so, for this, I threw out a method of passing views, you can implement this method to pass their own components.
Bottom track
@BuilderParam trackLayout?: (leftProgress: number, rightProgress: number, viewWidth: number) => void //自定义的轨道
if (this.trackLayout != undefined) {
this.trackLayout(this.leftProgress, this.rightProgress, this.viewWidth)
} else {
TrackView({
leftProgress: this.leftProgress,
rightProgress: this.rightProgress,
viewWidth: this.viewWidth,
trackAlignmentWidth: this.trackAlignmentWidth,
trackSelectColor: this.trackSelectColor,
trackNormalColor: this.trackNormalColor
})
}
in the business layer, it is enough to implement trackLayout, and some special styles can be implemented according to the progress of the left and right, as well as the width of the components.
@Builder
trackLayout(leftProgress: number, rightProgress: number, viewWidth: number) {
}
Middle Border
the Middle Border has nothing to say, it is a simple border. Of course, I also threw out a method to set the border by myself.
if (this.trackBgLayout != undefined) {
this.trackBgLayout()
} else {
Column().width("100%")
.height("100%")
.border(this.trackBgBorder)
}
Upper slider
the upper slider, the most important is to control the gesture of its slider, whether left or right, be sure to record the coordinates of the last lift, the other is to control the maximum movement distance of the left and right, the other to nothing, the main code is as follows:
Column() {
if (this.leftPointerLayout != undefined) {
this.leftPointerLayout()
} else {
Divider()
.strokeWidth(this.pointerLineWidth)
.height(this.pointerLineHeight)
.vertical(true)
.lineCap(this.pointerLineCap)
.color(this.pointerLineColor)
}
}
.width(this.pointerWidth)
.height(this.pointerHeight)
.justifyContent(FlexAlign.Center)
.borderRadius(this.leftPointerBorder)
.backgroundColor(this.leftPointerBgColor)
.margin({ left: this.trackMarginLeft })
.onTouch((event) => {
switch (event.type) {
case TouchType.Down:
this.pointerLeftMargin = event.touches[0].x
break;
case TouchType.Move:
let rightMargin = this.viewWidth - this.trackMarginRight - Number(this.pointerWidth)
let upData = event.touches[0].displayX
let moveX = upData - this.viewMarginLeft
let pointerValue = moveX - this.pointerLeftMargin
if (pointerValue >= 0 && (pointerValue + Number(this.pointerWidth)) <= rightMargin) {
this.trackMarginLeft = pointerValue
}
let percentage = this.trackMarginLeft / (this.viewWidth - Number(this.pointerWidth) * 2) //百分比
let progress = Math.round(percentage * 100) //进度
this.leftProgress = progress
if (this.onLeftProgress != undefined) {
this.onLeftProgress(progress)
}
break
case TouchType.Up:
if (this.onLeftEndProgress != undefined) {
this.onLeftEndProgress(this.leftProgress)
}
break
}
})
three, open source address and function use
address of central warehouse
in order to make it better for everyone to use, it has been submitted to the central warehouse so that everyone can use it remotely and directly.
https://ohpm.openharmony.cn/#/cn/detail/@abner%2Ftrack
quick Use
method 1: in the Terminal window, run the following command to install the third-party package. DevEco Studio automatically adds the third-party package dependency to the project oh-package.json5.
Suggestion: Execute the command under the module path used.
ohpm install @abner/track
Method 2: Set the three-party package dependency in the project oh-package.json5. The configuration example is as follows:
"dependencies": { "@abner/track": "^1.0.0"}
related Functions
1. Ordinary use
TrackProgress({
pointerWidth: 20,
onLeftProgress: (progress: number) => {
console.log("===left:" + progress)
},
onRightProgress: (progress: number) => {
console.log("===right:" + progress)
}
})
2. Obtain progress
TrackProgress({
pointerWidth: 20,
onLeftProgress: (progress: number) => {
console.log("===left:" + progress)
},
onRightProgress: (progress: number) => {
console.log("===right:" + progress)
}
})
3. Change the color
TrackProgress({
pointerWidth: 20,
leftPointerBgColor: Color.Orange,
rightPointerBgColor: Color.Orange,
trackSelectColor: Color.Orange,
trackBgBorder: { width: 1, color: Color.Orange, radius: 5 },
onLeftProgress: (progress: number) => {
console.log("===left:" + progress)
},
onRightProgress: (progress: number) => {
console.log("===right:" + progress)
}
})
4. Custom slider
TrackProgress({
pointerWidth: 20,
leftPointerLayout: this.pointerLayout,
rightPointerLayout: this.pointerLayout,
onLeftProgress: (progress: number) => {
console.log("===left:" + progress)
},
onRightProgress: (progress: number) => {
console.log("===right:" + progress)
}
})
5. Custom track
TrackProgress({
pointerWidth: 20,
trackLayout: this.trackLayout,
trackBgLayout: this.trackBgLayout,
onLeftProgress: (progress: number) => {
console.log("===left:" + progress)
},
onRightProgress: (progress: number) => {
console.log("===right:" + progress)
}
})
related Properties
property | type | overview |
---|---|---|
progressWidth | Length | width of the progress bar |
progressHeight | Length | the height of the progress bar defaults to 50 |
onLeftProgress | (progress: number) => void | left Slide Progress |
onLeftEndProgress | (progress: number) => void | end of left slide progress |
onRightProgress | (progress: number) => void | right Slide Progress |
onRightEndProgress | (progress: number) => void | progress at the end of the Right Slide |
pointerHeight | Length | height of the slider |
trackLayout | (leftProgress: number, rightProgress: number, viewWidth: number) => void | custom Track |
trackBgLayout | () => void | custom track background view |
leftPointerLayout | () => void | left Slider View |
rightPointerLayout | () => void | right Slider View |
leftPointerBgColor | ResourceColor | left slider background color |
rightPointerBgColor | ResourceColor | right slider background color |
leftPointerBorder | Length/BorderRadiuses/ LocalizedBorderRadiuses | the fillet degree of the left slider |
rightPointerBorder | Length/BorderRadiuses/ LocalizedBorderRadiuses | right slider fillet degree |
trackBgBorder | BorderOptions | orbital background Border |
trackSelectColor | ResourceColor | swipe to select the background |
trackNormalColor | ResourceColor | swipe unselected background |
pointerLineColor | ResourceColor | slider Line Color |
pointerLineWidth | number /string | slider line width |
pointerLineHeight | slider Line Height | |
pointerLineCap | LineCapStyle | slider Line Type |
IV. Relevant Summary
at present, the left slider and the right slider return percentages. In actual development, both sides may be time, so the current sliding time needs to be calculated according to the progress.
In many editing scenes, there will be multiple clips, such as segmentation, then there will be multiple track clips. In actual requirements, the creation of the entire track also requires dynamic configuration, that is, specific analysis of specific problems.
Top comments (0)