HarmonyOS鸿蒙Next中Canvas的onReady中绘制逻辑要如何才能监听@Observed Map内部发生变化?

HarmonyOS鸿蒙Next中Canvas的onReady中绘制逻辑要如何才能监听@Observed Map内部发生变化? 运行下面的UI,可以看到只有Text可以响应Map里的数据更新,Canvas不会更新,我想知道怎样改才能让绘制逻辑也能观察Map内部变量触发更新?

[@Observed](/user/Observed)
class ObservedMap<K, V> extends Map<K, V> {}

@Entry
@Component
struct Index {
  @State map: ObservedMap<number, number> = new ObservedMap()

  aboutToAppear(): void {
    this.map.set(1, 0)
    this.map.set(2, 0.25)
    this.map.set(3, 0.5)
    this.map.set(4, 0.75)

    // key为1的数据每隔一秒更新
    let count = 0
    setInterval(() => {
      if (count % 2 == 0) {
        this.map.set(1, 0)
      } else {
        this.map.set(1, 0.5)
      }
      count++
    }, 1000)
  }

  build() {
    Stack() {
      ReceiptIconWrap({
        map: this.map
      }).width("100%").height("100%")
    }
    .height('100%')
    .width('100%')
  }
}

@Component
export struct ReceiptIconWrap {
  @ObjectLink map: ObservedMap<number, number>
  private someId: number[] = [1, 2, 3, 4]

  build() {
    Column() {
      ForEach(this.someId, (item: number, index: number) => {
        Text(this.map.get(item)?.toString())
        ReceiptIcon({
          percent: this.map.get(item)
        }).width(50).height(50)
      })
    }.width("100%").height("100%")
  }
}

const FULL_CIRCLE_RADIAN = Math.PI * 2 // 360°的弧度
const START_RADIAN = -0.25 * FULL_CIRCLE_RADIAN
const CHECK_GREEN = "#00CC66"

@Component
export struct ReceiptIcon {
  @State radiusPx: number = 0
  @State @Watch('drawArc') percent: number = 0.5 // ∈[0, 1]
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  // 根据Percent绘制圆弧
  drawArc() {
    this.context.beginPath()
    this.context.fillStyle = CHECK_GREEN
    this.context.arc(
      this.context.width / 2,
      this.context.height / 2,
      this.radiusPx,
      START_RADIAN,
      this.percent * FULL_CIRCLE_RADIAN + START_RADIAN
    )
    if (this.percent < 1) {
      this.context.lineTo(this.context.width / 2, this.context.height / 2)
      this.context.lineTo(this.context.width / 2, this.context.height / 2)
    }
    this.context.fill()
  }

  build() {
    Canvas(this.context)
      .onSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => {
        this.radiusPx = Math.min(Number(newValue.width ?? 0), Number(newValue.height ?? 0)) * 0.5
      }).onReady(() => {
      if (this.percent < 0) {
        return
      }
      this.drawArc()
    })
  }
}

更多关于HarmonyOS鸿蒙Next中Canvas的onReady中绘制逻辑要如何才能监听@Observed Map内部发生变化?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

将监听中的@State改成@Prop即可。 onReady 定义,内部无法监听State变量修改,父子组件传参用Prop即可。

还有您定时器定义的k

let count = 0

  setInterval(() => {
    if (count % 2 == 0) {
      this.map.set(1, 0)
    } else {
      this.map.set(1, 0.5)
    }
    count++;
  }, 1000)

ey,仅仅=是修改了map的 key=1 的 value

更多关于HarmonyOS鸿蒙Next中Canvas的onReady中绘制逻辑要如何才能监听@Observed Map内部发生变化?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,如果你在Canvas的onReady方法中绘制逻辑,并且希望监听@Observed修饰的Map内部的变化,可以通过以下步骤实现:

  1. 使用@Observed修饰Map:确保你的Map对象被@Observed修饰,这样ArkUI框架可以自动监听其内部的变化。

  2. 使用@State@Link修饰状态变量:在组件中,使用@State@Link修饰与Map相关的状态变量,以便在Map发生变化时触发UI更新。

  3. 在Canvas的onReady中绑定绘制逻辑:在onReady方法中,你可以直接使用Map中的数据来进行绘制。当Map发生变化时,ArkUI会自动触发组件的重新渲染,并再次调用onReady方法,从而更新Canvas内容。

  4. 监听Map变化:如果你需要在Map变化时执行特定的逻辑,可以使用@Watch装饰器来监听Map的变化,并在变化时触发相应的回调函数。

@Entry
@Component
struct MyCanvasComponent {
  @Observed private myMap: Map<string, string> = new Map();

  @State private isReady: boolean = false;

  build() {
    Column() {
      Canvas(this.onReady)
        .width('100%')
        .height('100%')
    }
  }

  onReady(ctx: CanvasRenderingContext2D) {
    // 绘制逻辑
    this.myMap.forEach((value, key) => {
      // 使用Map中的数据绘制内容
    });

    // 监听Map变化
    this.$watch('myMap', () => {
      // Map变化时执行的逻辑
    });
  }
}

通过以上方法,你可以在CanvasonReady中监听@Observed Map内部的变化,并在变化时更新绘制内容。

在HarmonyOS鸿蒙Next中,若要在CanvasonReady中监听@Observed Map的变化,可以使用@Observed装饰器标记Map,并在onReady中通过@Watch装饰器监听Map的变化。当Map内容更新时,@Watch会触发回调函数,你可以在回调中重新执行绘制逻辑。确保在onReady中正确绑定@Watch监听器,以便实时响应Map的变化并更新Canvas内容。

回到顶部