自学内容网 自学内容网

HarmonyOS(66) ArkUI FrameNode实现自定义View

1、前言

HarmonyOS(65) ArkUI FrameNode详解一文中详细说明了FrameNode的作用,以及怎么对节点的查询、增加、删除功能。FrameNode还有一个重要的功能就是实现自定义View,类似Android一样。本篇博文通过一个demo来说明如何通过FrameNode实现自定义View. 实现效果如下:
在这里插入图片描述

  • 绿色矩形是自定义的MyFrameNode
  • 粉色矩形是MyFrameNode的childFrameNode
  • 红色矩形框是通过。FrameNodeonDraw方法绘制的图形
  • FrameNode提供的invalidate方法可以是的FrameNode重新绘制,也就是执行onDraw方法,类比Android的invalidate方法。
  • FrameNode提供的setNeedsLayout,将当前 FrameNode提供的节点标记,在下一帧会重新布局,有点类似于Android的requestLayout方法。
    下面就分析下怎么实现的,通过本篇博文你可以了解到如何自定义FrameNode以及NodeController的用法:

2、MyFrameNode实现

2.1、onDraw方法绘制红色矩形框

通过重写 FrameNodeonDraw方法,可以自定义 FrameNode的绘制内容。绘制上图红色矩形边框的代码如下:

//自定义FrameNode
class MyFrameNode extends FrameNode {
   
  public width: number = 100;
  public offsetY: number = 0;
  private space: number = 1;
  //省略了onMeasure方法
  //省略了onLayout方法
  //绘制红色矩形边框
  onDraw(context: DrawContext) {
   
    //获取画布
    const canvas = context.canvas;
    //初始化画笔
    const pen = new drawing.Pen();
    //设置边框宽度
    pen.setStrokeWidth(15);
    //设置边框颜色为红色,RGB模式
    pen.setColor({
    alpha: 255, red: 255, green: 0, blue: 0 });
    //画布绑定画笔
    canvas.attachPen(pen);
    //绘制画笔
    canvas.drawRect({
   
      left: 50,
      right: this.width + 50,
      top: 50,
      bottom: this.width + 50,
    });
    //释放画笔
    canvas.detachPen();
  }

  //通过动态修改width来修改红色矩形边框的right和botton
  addWidth() {
   
    this.width = (this.width + 10) % 50 + 100;
    // 页面重绘
     this.invalidate();
  }
}//end MyFrameNode


//点击上图Invalidate方法的代码如下
 Button('Invalidate')
          .margin(10)
          .onClick(() => {
   
            this.nodeController?.myFrameNode?.addWidth();
          })

通过上面代码我们可以注意下一个细节点,在绘制完成后要调用canvas.detachPen()及时释放相关资源。

2.2、onMeasure测量自定义FrameNode

  • onMeasure方法可以自定义 FrameNode的测量方式,使用measure方法可以主动传递布局约束触发重新测量,可以参考AndroidonMeasure方法。
//自定义childFrameNode 的布局约束
function GetChildLayoutConstraint(constraint: LayoutConstraint, child: FrameNode): LayoutConstraint {
   
  const size = child.getUserConfigSize();
  const width = Math.max(
    Math.min(constraint.maxSize.width, size.width.value),
    constraint.minSize.width
  );
  const height = Math.max(
    Math.min(constraint.maxSize.height, size.height.value),
    constraint.minSize.height
  );
  const finalSize: Size = {
    width, height };
  //返回一个自定义布局约束
  const res: LayoutConstraint = {
   
    maxSize: finalSize,
    minSize: finalSize,
    //子节点计算百分比时的尺寸基准
    percentReference: finalSize
  };

  return res;
}

//自定义MyFrameNode
class MyFrameNode extends FrameNode {
   

原文地址:https://blog.csdn.net/chunqiuwei/article/details/144363091

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!