HarmonyOS 鸿蒙Next 使用Canvas做一个类似进度条一样的图形,onReady能监听@state修饰的变量吗?

发布于 1周前 作者 phonegap100 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 使用Canvas做一个类似进度条一样的图形,onReady能监听@state修饰的变量吗? 使用Canvas进行绘制需要根据变量进行图形的变化,但是设置@state发现无法触发onReady方法(修改Canvas宽高后能触发,但是与我需求不符),请求有手动触发onReady的方式吗?或者如何设置能动态监控到@state修饰的变量?想要做一个类似进度条一样的图形

2 回复

可以使用@Watch注解,使用@Watch的变量在变化后可以触发自己定义的方法,这样就不用触发onReady方法了

//SliderPage.ets
@Entry
@Component
struct SliderPage {

  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  @State [@Watch](/user/Watch)('redRateChange') redRate: number = 0.5
  @State leftText: string = "123"
  @State rightText: string = "456"
  redRateChange(){
    let h = this.context.height
    let w = this.context.width

    let left = new Path2D()
    left.arc(5, 5, 4, Math.PI / 2, Math.PI / 2 * 3)
    left.moveTo(5, 1)
    left.lineTo((w - 15) * this.redRate, 1)
    left.lineTo((w - 15) * this.redRate - 5, 9)
    left.lineTo(5, 9)
    left.closePath()
    this.context.fillStyle = "#ff6d5b"
    this.context.fill(left)
    let center = new Path2D()
    center.moveTo((w - 15) * this.redRate + 5, 1)
    center.lineTo((w - 15) * this.redRate + 10, 1)
    center.lineTo((w - 15) * this.redRate + 5, 9)
    center.lineTo((w - 15) * this.redRate, 9)
    this.context.fillStyle = "#000000"
    this.context.fill(center)

    let right = new Path2D()
    right.moveTo((w - 15) * this.redRate + 15, 1)
    right.lineTo(w - 5, 1)
    right.lineTo(w - 5, 9)
    right.lineTo((w - 15) * this.redRate + 10, 9)
    right.moveTo(w - 5, 5)
    right.arc(w - 5, 5, 4, Math.PI / 2 * 3, Math.PI / 2)

    this.context.fillStyle = "#77439d"
    this.context.fill(right)
  }

  build() {
    Column({ space: 24 }) {
      Row({ space: 4 }) {
        Text(this.leftText)

        Canvas(this.context)
          .height(10)
          .layoutWeight(1)
          .onReady(() => {
            let h = this.context.height
            let w = this.context.width

            let left = new Path2D()
            left.arc(5, 5, 4, Math.PI / 2, Math.PI / 2 * 3)
            left.moveTo(5, 1)
            left.lineTo((w - 15) * this.redRate, 1)
            left.lineTo((w - 15) * this.redRate - 5, 9)
            left.lineTo(5, 9)
            left.closePath()
            this.context.fillStyle = "#ff6d5b"
            this.context.fill(left)

            let center = new Path2D()
            center.moveTo((w - 15) * this.redRate + 5, 1)
            center.lineTo((w - 15) * this.redRate + 10, 1)
            center.lineTo((w - 15) * this.redRate + 5, 9)
            center.lineTo((w - 15) * this.redRate, 9)
            this.context.fillStyle = "#000000"
            this.context.fill(center)
            let right = new Path2D()
            right.moveTo((w - 15) * this.redRate + 15, 1)
            right.lineTo(w - 5, 1)
            right.lineTo(w - 5, 9)
            right.lineTo((w - 15) * this.redRate + 10, 9)
            right.moveTo(w - 5, 5)
            right.arc(w - 5, 5, 4, Math.PI / 2 * 3, Math.PI / 2)

            this.context.fillStyle = "#77439d"
            this.context.fill(right)
          })

        Text(this.rightText)
      }
      .width("100%")
      .padding({ left: 16, right: 16 })

      Button("点我修改进度")
        .onClick(() => {
          this.redRate = 0.75
        })
      Button("点我修改进度及左右文字导致画板宽度变化")
        .onClick(() => {
          this.redRate = 0.25
          this.leftText = "1234"
          this.rightText = "5678"
        })
    }
  }
}

更多关于HarmonyOS 鸿蒙Next 使用Canvas做一个类似进度条一样的图形,onReady能监听@state修饰的变量吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用Canvas绘制类似进度条的图形是可行的。关于你的问题,onReady 方法确实可以监听由 @State 修饰的变量,但需要注意的是,onReady 主要是组件加载完成后的回调,它并不是专门用来监听状态变化的。

在鸿蒙系统中,如果你希望在状态变化时重新绘制图形,你应该使用 @Observed 注解来监听状态变量,或者通过组件的刷新机制来触发重绘。通常,你会在状态变量变化时调用某个方法来重新绘制Canvas上的内容。

例如,你可以有一个表示进度条的进度的状态变量,并在该变量变化时调用一个方法来更新Canvas上的图形。这个更新方法可以在组件的某个生命周期方法(如onStateChanged,如果鸿蒙提供了类似的方法)或者通过事件处理来调用。

不过,在鸿蒙的组件化开发中,更常见的是通过数据绑定和组件的自动刷新来实现UI的更新,而不是手动调用绘制方法。

如果你需要在onReady中做一些初始化工作,并且这些工作与状态变量有关,你可以确保在onReady执行时状态变量已经初始化完成。

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部