鸿蒙Next动态添加删除布局

2025-06-27 22:50:53
110次阅读
0个评论

背景案例:当我们应用中有一个输入功能,输入个数需要用户动态修改,这时原有的固定布局就不能满足这个需求了,因此就要用到动态添加布局。 简单演示演示.gif 实现原理: 自定义声明式节点 (BuilderNode)提供能够挂载系统组件的能力,支持采用无状态的UI方式,通过全局自定义构建函数@Builder定制组件树。 一个新建的BuildNode在build之后才能通过getFrameNode获取到一个指向根节点的FrameNode对象,否则返回null 示例.PNG 实现过程: 1.定义一个全局的Build修饰的布局用于动态添加到容器中 2.定义一个参数对象,可以传入参数或者接收回调 3.添加节点到布局中 注意: 1.@Builder嵌套使用的时候需要保证内外的@Builder方法的入参对象一致。最外层的@Builder只支持一个入参。需要操作BuilderNode中的对象时,需要保证其引用不被回收。 2.若前端对象BuilderNode无法释放,容易导致内存泄漏。建议在不再需要对该BuilderNode对象进行操作时,开发者应主动调用dispose释放后端节点,以减少引用关系的复杂性,降低内存泄漏的风险。 实现源码

import { BuilderNode, NodeContent } from '@kit.ArkUI';
import { ArrayList } from '@kit.ArkTS';

class User {
  name: string = ''
  phone: string = ''
}

interface ParamsInterface {
  user: User
  save: (user: User) => void;
  delete: (user: User) => void
}

@Builder
function buildChildViw(params: ParamsInterface) {
  Column({ space: 5 }) {
    TextInput({ placeholder: '输入姓名' }).onChange((e) => {
      params.user.name = e
    })
    TextInput({ placeholder: '输入手机号' }).onChange((e) => {
      params.user.phone = e
    })
    Row(){
      Button('确定').onClick(() => {
        params.save(params.user)
      })
      Button('删除').onClick(() => {
        params.delete(params.user)
      })
    }
  }
}

@Entry
@ComponentV2
struct AddNodeTest {
  content: NodeContent = new NodeContent();
  @Local paramMap: ArrayList<User> = new ArrayList();
  @Local inputInfo: string = ''
  getInputUserInfo() {
    this.inputInfo=''
    this.paramMap.forEach((value: User, index?: number) => {
      this.inputInfo += index + ' name:' + value.name + ' phone:' + value.phone + '\n'
    });
  }
  build() {
    Column({ space: 10 }) {
      ContentSlot(this.content)
      Button('添加联系人')
        .onClick(() => {
          let buildNode = new BuilderNode<[ParamsInterface]>(this.getUIContext());
          buildNode.build(wrapBuilder<[ParamsInterface]>(buildChildViw), {
            user: new User(), save: (user: User) => {
              this.paramMap.add(user)
            }, delete: (user: User) => {
              this.paramMap.remove(user)
              this.content.removeFrameNode(buildNode.getFrameNode())
            }
          }, { nestingBuilderSupported: true });
          this.content.addFrameNode(buildNode.getFrameNode());
        })
      Button('显示联系人').onClick(() => {
        this.getInputUserInfo()
      })
      Text(this.inputInfo)
    }
    .width('100%')
    .height('100%')
  }
}

代码有不严谨的地方,只是演示一下动态添加布局的方法,实际开发中还得根据需求进行修改完善。

收藏00

登录 后评论。没有帐号? 注册 一个。