HarmonyOS鸿蒙Next中不使用@State状态变量,如何控制Refresh组件刷新状态

HarmonyOS鸿蒙Next中不使用@State状态变量,如何控制Refresh组件刷新状态

import { BuilderNode, FrameNode, NodeController, typeNode, UIContext } from "@kit.ArkUI"

@Builder
export function TestCreateWaterFlowBuilder() {
  TestCreateWaterFlow()
}

[@Component](/user/Component)
export struct TestCreateWaterFlow {
  uiContext: UIContext = this.getUIContext()
  params: Params | null = null
  pageController: MyNodeController | null = null
  refreshContent: RefreshContentNodeController | null = null

  aboutToAppear(): void {
    this.refreshContent = new RefreshContentNodeController()
    let child = typeNode.createNode(this.uiContext, "Text")
    child.initialize("Hello World!")
      .width('100%')
      .height(60)
      .lineHeight(60)
      .textAlign(TextAlign.Center)
    this.params = new Params(child, this.refreshContent).setOnStateChange(state => {
      if (state === RefreshStatus.Refresh) {
        // 模拟500ms后刷新完成,此时需要将RefreshStatus变为Done
        setTimeout(()=>{
          // 此处的代码应该如何设计
        }, 500)
      }
    })
    this.pageController = new MyNodeController(this.params)
  }

  build() {
    NavDestination() {
      NodeContainer(this.pageController)
        .width("100%")
        .height("100%")
    }
  }
}

class Params {
  child: FrameNode
  controller: RefreshContentNodeController
  refreshing?: boolean
  onStateChange: (state: RefreshStatus) => void = () => {
  }

  constructor(child: FrameNode, controller: RefreshContentNodeController, refreshing?: boolean) {
    this.child = child
    this.controller = controller
    this.refreshing = refreshing
  }

  setOnStateChange(onStateChange: (state: RefreshStatus) => void) {
    this.onStateChange = onStateChange
    return this
  }
}


@Builder
function RefreshNode(params: Params) {
  Refresh({ refreshing: params.refreshing }) {
    NodeContainer(params.controller)
      .width('100%')
      .height('100%')
      .onAppear(() => {
        params.controller?.appendChild(params.child)
      })
  }
  .onStateChange(state => {
    params.onStateChange(state)
    console.log(`====>${JSON.stringify(state)}`)
  })
}

class MyNodeController extends NodeController {
  rootNode: FrameNode | null = null
  params: Params

  constructor(params: Params) {
    super()
    this.params = params
  }

  makeNode(uiContext: UIContext): FrameNode | null {
    if (!this.rootNode) {
      let builderNode = new BuilderNode<[Params]>(uiContext)
      builderNode.build(wrapBuilder(RefreshNode), this.params)
      this.rootNode = builderNode.getFrameNode()
    }
    return this.rootNode
  }

  appendChild(childNode: FrameNode): void {
    this.rootNode?.appendChild(childNode)
  }

  clearChildren() {
    this.rootNode?.clearChildren()
  }
}

class RefreshContentNodeController extends NodeController {
  private rootNode: FrameNode | null = null

  makeNode(uiContext: UIContext): FrameNode | null {
    if (!this.rootNode) {
      this.rootNode = new FrameNode(uiContext)
    }
    return this.rootNode
  }

  appendChild(child: FrameNode) {
    this.rootNode?.appendChild(child)
  }
}

如果想在500ms后将刷新状态变为完成如何实现代码 或者是否有其他使用@Component然后用状态变量去实现动态挂载的方法吗


更多关于HarmonyOS鸿蒙Next中不使用@State状态变量,如何控制Refresh组件刷新状态的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

已解决,使用builderNode的update方法可以变更状态

import { BuilderNode, FrameNode, NodeController, typeNode, UIContext } from "@kit.ArkUI"

@Builder
export function TestCreateWaterFlowBuilder() {
  TestCreateWaterFlow()
}

@Component
export struct TestCreateWaterFlow {
  uiContext: UIContext = this.getUIContext()
  params: Params | null = null
  pageController: MyNodeController | null = null
  refreshContent: RefreshContentNodeController | null = null

  aboutToAppear(): void {
    this.refreshContent = new RefreshContentNodeController()
    let child = typeNode.createNode(this.uiContext, "Text")
    child.initialize("Hello World!")
      .width('100%')
      .height(60)
      .lineHeight(60)
      .textAlign(TextAlign.Center)
    this.params = new Params(child, this.refreshContent).setOnStateChange(state => {
      if (state === RefreshStatus.Refresh) {
        setTimeout(() => {
          //===========================================================================
          this.pageController!.onRefreshed()
          //===========================================================================
        }, 500)
      }
    })
    this.pageController = new MyNodeController(this.params)
  }

  build() {
    NavDestination() {
      NodeContainer(this.pageController)
        .width("100%")
        .height("100%")
    }
  }
}

class Params {
  child: FrameNode
  controller: RefreshContentNodeController
  refreshing?: boolean
  onStateChange: (state: RefreshStatus) => void = () => {
  }

  constructor(child: FrameNode, controller: RefreshContentNodeController, refreshing?: boolean) {
    this.child = child
    this.controller = controller
    this.refreshing = refreshing
  }

  setOnStateChange(onStateChange: (state: RefreshStatus) => void) {
    this.onStateChange = onStateChange
    return this
  }
}


@Builder
function RefreshNode(params: Params) {
  Refresh({ refreshing: params.refreshing }) {
    NodeContainer(params.controller)
      .width('100%')
      .height('100%')
      .onAppear(() => {
        params.controller?.appendChild(params.child)
      })
  }
  .onStateChange(state => {
    params.onStateChange(state)
    console.log(`====>${JSON.stringify(state)}`)
  })
}

class MyNodeController extends NodeController {
  
  //===========================================================================
  builderNode: BuilderNode<[Params]> | null = null
  //===========================================================================
  
  rootNode: FrameNode | null = null
  
  //===========================================================================
  params: Params
  //===========================================================================
  
  uiContext: UIContext | null = null

  constructor(params: Params) {
    super()
    this.params = params
  }

  makeNode(uiContext: UIContext): FrameNode | null {
    this.uiContext = uiContext
    if (!this.rootNode) {
      this.builderNode = new BuilderNode<[Params]>(uiContext)
      this.builderNode.build(wrapBuilder(RefreshNode), this.params)
      this.rootNode = this.builderNode.getFrameNode()
    }
    return this.rootNode
  }

  appendChild(childNode: FrameNode): void {
    this.rootNode?.appendChild(childNode)
  }

  clearChildren() {
    this.rootNode?.clearChildren()
  }

  //===========================================================================
  onRefreshed() {
    // 此处可以不设置:示例代码中params的refreshing没有做改变
    this.params.refreshing = false
    this.builderNode?.update(this.params)
  }
  //===========================================================================
}

class RefreshContentNodeController extends NodeController {
  private rootNode: FrameNode | null = null

  makeNode(uiContext: UIContext): FrameNode | null {
    if (!this.rootNode) {
      this.rootNode = new FrameNode(uiContext)
    }
    return this.rootNode
  }

  appendChild(child: FrameNode) {
    this.rootNode?.appendChild(child)
  }
}

更多关于HarmonyOS鸿蒙Next中不使用@State状态变量,如何控制Refresh组件刷新状态的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,若不使用@State状态变量,可通过@Provide@Consume装饰器实现跨组件状态管理。在父组件使用@Provide声明状态变量,子组件通过@Consume接收并响应变化,从而控制Refresh组件的刷新状态。此外,也可借助@Watch监听普通变量变化,在变量更新时手动触发Refresh组件的刷新方法。

在HarmonyOS Next中,不使用@State状态变量控制Refresh组件刷新状态,可以通过NodeController和回调机制实现。

在您的代码中,当刷新状态变为Refresh时,需要在500ms后将状态改为Done。可以直接通过Params对象中的controller来更新状态:

setTimeout(() => {
  // 通过RefreshContentNodeController更新刷新状态
  this.params?.controller?.updateRefreshState(false)
}, 500)

同时需要在RefreshContentNodeController中添加相应方法:

class RefreshContentNodeController extends NodeController {
  // ... 现有代码
  
  updateRefreshState(refreshing: boolean): void {
    // 通过FrameNode的属性更新来触发Refresh组件状态变化
    if (this.rootNode) {
      // 这里需要根据实际API设置刷新状态
      // 例如:this.rootNode.setAttribute('refreshing', refreshing)
    }
  }
}

对于动态挂载的替代方案,可以使用@Provide/@Consume装饰器配合NodeController实现组件间的状态管理,避免直接使用@State。这种方式通过NodeController的生命周期方法和FrameNode的操作来控制组件树的动态更新,实现与状态变量类似的效果但更加灵活。

回到顶部