HarmonyOS Next开发学习手册——同层渲染绘制Video和Button组件

同层渲染是ArkWeb组件为应用提供原生组件和Web元素渲染在同一层级的能力。支持的组件范围请参考 NodeRenderType 说明。

  • 使用前请在module.json5中添加网络权限,添加方法请参考 在配置文件中声明权限 。
"requestPermissions":[
    {
      "name" : "ohos.permission.INTERNET"
    }
  ]

约束限制

使用同层渲染的功能时会有如下限制。

  • 不支持W3C规格标准标签定义为同层标签。

  • 不支持同时配置Object标签和Embed标签作为同层渲染标签。

  • 一个页面内同层标签的个数建议不超过五个,超过这个范围性能体验可能得不到保障。

  • 同层标签最大高度不超过8192px,最大纹理大小为8192px。

  • Web组件嵌套Web只支持一层嵌套,不支持多层嵌套。如果多层嵌套,会显示 “该插件不受支持”。

  • 同层渲染区域支持的触屏事件包括:滑动、点击、缩放、长按,不支持拖拽。

  • 同层渲染区域不支持鼠标、键盘、触摸板事件

  • 开启同层渲染后,Web组件打开的所有Web页面将不支持统一渲染模式 RenderMode 。

绘制XComponent+AVPlayer和Button组件

使能同层渲染模式

开发者可通过 enableNativeEmbedMode() 控制同层渲染开关。Html文件中需要显式使用embed标签,并且embed标签内type必须以“native/”开头。同层标签对应的元素区域的背景为透明。

  • 应用侧代码组件使用示例。
// HAP's src/main/ets/pages/Index.ets
// 创建NodeController
import { webview } from '@kit.ArkWeb';
import { UIContext, NodeController, BuilderNode, NodeRenderType, FrameNode } from "@kit.ArkUI";
import { AVPlayerDemo } from './PlayerDemo';

@Observed
declare class Params {
  textOne : string
  textTwo : string
  width : number
  height : number
}

declare class nodeControllerParams {
  surfaceId : string
  type : string
  renderType : NodeRenderType
  embedId : string
  width : number
  height : number
}

// 用于控制和反馈对应的NodeContainer上的节点的行为,需要与NodeContainer一起使用。
class MyNodeController extends NodeController {
  private rootNode: BuilderNode<[Params]> | undefined | null;
  private embedId_ : string = "";
  private surfaceId_ : string = "";
  private renderType_ :NodeRenderType = NodeRenderType.RENDER_TYPE_DISPLAY;
  private width_ : number = 0;
  private height_ : number = 0;
  private type_ : string = "";
  private isDestroy_ : boolean = false;

  setRenderOption(params : nodeControllerParams) {
    this.surfaceId_ = params.surfaceId;
    this.renderType_ = params.renderType;
    this.embedId_ = params.embedId;
    this.width_ = params.width;
    this.height_ = params.height;
    this.type_ = params.type;
  }
  // 必须要重写的方法,用于构建节点数、返回节点数挂载在对应NodeContainer中。
  // 在对应NodeContainer创建的时候调用、或者通过rebuild方法调用刷新。
  makeNode(uiContext: UIContext): FrameNode | null{
    if (this.isDestroy_) { // rootNode为null
      return null;
    }
    if (!this.rootNode) { // rootNode 为undefined时
      this.rootNode = new BuilderNode(uiContext, { surfaceId: this.surfaceId_, type: this.renderType_});
      if (this.type_ === 'native/video') {
        this.rootNode.build(wrapBuilder(VideoBuilder), {textOne: "myButton", width : this.width_, height : this.height_});
      } else {
        // other
      }
    }
    // 返回FrameNode节点。
    return this.rootNode.getFrameNode();
  }

  setBuilderNode(rootNode: BuilderNode<Params[]> | null): void{
    this.rootNode = rootNode;
  }

  getBuilderNode(): BuilderNode<[Params]> | undefined | null{
    return this.rootNode;
  }

  updateNode(arg: Object): void {
    this.rootNode?.update(arg);
  }
  getEmbedId() : string {
    return this.embedId_;
  }

  setDestroy(isDestroy : boolean) : void {
    this.isDestroy_ = isDestroy;
    if (this.isDestroy_) {
      this.rootNode = null;
    }
  }

  postEvent(event: TouchEvent | undefined) : boolean {
    return this.rootNode?.postTouchEvent(event) as boolean
  }
}

@Component
struct VideoComponent {
  @ObjectLink params: Params
  @State bkColor: Color = Color.Red
  mXComponentController: XComponentController = new XComponentController();
  @State player_changed: boolean = false;
  player?: AVPlayerDemo;

  build() {
    Column() {
      Button(this.params.textOne)

      XComponent({ id: 'video_player_id', type: XComponentType.SURFACE, controller: this.mXComponentController})
        .border({width: 1, color: Color.Red})
        .onLoad(() => {
          this.player = new AVPlayerDemo();
          this.player.setSurfaceID(this.mXComponentController.getXComponentSurfaceId());
          this.player_changed = !this.player_changed;
          this.player.avPlayerLiveDemo()
        })
        .width(300)
        .height(200)
    }
    //自定义组件中的最外层容器组件宽高应该为同层标签的宽高
    .width(this.params.width)
    .height(this.params.height)
  }
}
// @Builder中为动态组件的具体组件内容。
@Builder
function VideoBuilder(params: Params) {
  VideoComponent({ params: params })
    .backgroundColor(Color.Gray)
}

@Entry
@Component
struct WebIndex {
  browserTabController: WebviewController = new webview.WebviewController()
  private nodeControllerMap: Map<string, MyNodeController> = new Map();
  @State componentIdArr: Array<string> =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值