效果展示
在ArkUI中,有两种自定义绘制的组件,Shape和Canvas。其中Shape主要用于绘制简单的2D图形,而Canvas支持更多复杂的效果,包括动画和渐变等,因此这里我们自定义view选用Canvas。
Canvas的绘制操作需要在他的onReady中进行,onReady回调时Canvas已经初始化完毕,此时可以拿到实际宽高。
1.首先来画SeekBar背景浅色的线(圆角矩形),因为Canvas的api里没有支持矩形,因此这里我们使用Path2D先描绘出一个闭合的Path,然后上色:
//用来配置CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象的参数,包括是否开启抗锯齿。true表明开启抗锯齿
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
Canvas(this.context)
.onReady(() => {
//线条两边变圆
this.context.lineCap = 'round'
//线条粗细(往两边画)
this.context.lineWidth = 5
//画笔颜色
this.context.fillStyle = '#3dffffff'
this.context.beginPath()
this.context.moveTo(100, 100)
this.context.lineTo(300, 100)
//根据当前path执行绘制
this.context.stroke()
})
2.再画一下滑竿上的小球球:
this.context.fillStyle = '#ff0000'
let region = new Path2D()
let x = 100 + 200 * this.progress
region.arc(x, 100, 10, 0, 6.28)
this.context.fill(region)
3.处理一下触摸事件,更新下进度:
.onTouch((event: TouchEvent) => {
this.progress = event.touches[0].x / this.progressBarWidth
})
逆天了,State更新竟然没有触发onReady刷新,看了一下官方文档,只有Canvas大小发生变化的时候才会清除发布重新走onReady。目前想了个办法,其实所谓的渲染就是调用CanvasRenderingContext2D的api,那我干脆把draw的这部分代码(onReady中的部分)抽出来,在想调用的时候调用,不知道这是不是最佳实践:
.onTouch((event: TouchEvent) => {
this.progress = event.touches[0].x / this.progressBarWidth
this.context.clearRect(0,0, 300, 200)
this.draw()
})
这里先清一下画布,然后重新渲染。