diff --git a/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleViewA.ets b/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleViewA.ets index 03ffb46d2d7..19947071e06 100644 --- a/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleViewA.ets +++ b/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleViewA.ets @@ -84,6 +84,8 @@ export struct ExampleComponentA { ForEach(this.children, (item: HippyRenderBaseView) => { buildHippyRenderView(item, null) }, (item: HippyRenderBaseView) => item.tag + '') + // 该自定义组件有Hippy子组件或其它自定义子组件时,必须加Slot来衔接子组件 + ContentSlot(this.renderView.childSlot) } .applyRenderViewBaseAttr(this.renderView) } diff --git a/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleViewB.ets b/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleViewB.ets index 7aafbfd30d3..1adab56e949 100644 --- a/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleViewB.ets +++ b/framework/examples/ohos-demo/src/main/ets/hippy_extend/ExampleViewB.ets @@ -62,6 +62,8 @@ export struct ExampleComponentB { build() { Stack() { Text("This is a custom component B.") + // 该自定义组件有Hippy子组件或其它自定义子组件时,必须加Slot来衔接子组件 + ContentSlot(this.renderView.childSlot) } .applyRenderViewBaseAttr(this.renderView) } diff --git a/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/components/custom_ts_view.h b/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/components/custom_ts_view.h index 23ee05761af..39ab4834d8b 100644 --- a/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/components/custom_ts_view.h +++ b/framework/ohos/src/main/cpp/impl/renderer/native/include/renderer/components/custom_ts_view.h @@ -32,10 +32,10 @@ inline namespace native { class CustomTsView : public BaseView { public: - CustomTsView(std::shared_ptr &ctx, ArkUI_NodeHandle nodeHandle); + CustomTsView(std::shared_ptr &ctx, ArkUI_NodeHandle nodeHandle, ArkUI_NodeContentHandle contentHandle); ~CustomTsView(); - StackNode *GetLocalRootArkUINode() override; + CustomTsNode *GetLocalRootArkUINode() override; void CreateArkUINodeImpl() override; void DestroyArkUINodeImpl() override; bool SetPropImpl(const std::string &propKey, const HippyValue &propValue) override; @@ -50,11 +50,11 @@ class CustomTsView : public BaseView { void OnCustomTsViewChildInserted(uint32_t tag, std::shared_ptr const &childView, int32_t index); void OnCustomTsViewChildRemoved(uint32_t tag, std::shared_ptr const &childView, int32_t index); - std::shared_ptr containerNode_; std::shared_ptr tsNode_; - std::shared_ptr subContainerNode_; + std::shared_ptr contentNode_; ArkUI_NodeHandle customNodeHandle_ = nullptr; + ArkUI_NodeContentHandle contentHandle_ = nullptr; }; } // namespace native diff --git a/framework/ohos/src/main/cpp/impl/renderer/native/src/components/custom_ts_view.cc b/framework/ohos/src/main/cpp/impl/renderer/native/src/components/custom_ts_view.cc index 8a0f398c39e..4ea9345546a 100644 --- a/framework/ohos/src/main/cpp/impl/renderer/native/src/components/custom_ts_view.cc +++ b/framework/ohos/src/main/cpp/impl/renderer/native/src/components/custom_ts_view.cc @@ -32,51 +32,50 @@ namespace hippy { inline namespace render { inline namespace native { -CustomTsView::CustomTsView(std::shared_ptr &ctx, ArkUI_NodeHandle nodeHandle) : BaseView(ctx), customNodeHandle_(nodeHandle) { +CustomTsView::CustomTsView(std::shared_ptr &ctx, ArkUI_NodeHandle nodeHandle, + ArkUI_NodeContentHandle contentHandle) : BaseView(ctx), customNodeHandle_(nodeHandle), contentHandle_(contentHandle) { } CustomTsView::~CustomTsView() { if (!children_.empty()) { - if (subContainerNode_) { + if (contentNode_) { for (const auto &child : children_) { - subContainerNode_->RemoveChild(child->GetLocalRootArkUINode()); + contentNode_->RemoveChild(child->GetLocalRootArkUINode()); } } children_.clear(); } - if (containerNode_) { - containerNode_->RemoveChild(tsNode_.get()); - containerNode_->RemoveChild(subContainerNode_.get()); - } if (customNodeHandle_) { NativeNodeApi::GetInstance()->disposeNode(customNodeHandle_); customNodeHandle_ = nullptr; } + contentHandle_ = nullptr; } -StackNode *CustomTsView::GetLocalRootArkUINode() { - return containerNode_.get(); +CustomTsNode *CustomTsView::GetLocalRootArkUINode() { + return tsNode_.get(); } void CustomTsView::CreateArkUINodeImpl() { - containerNode_ = std::make_shared(); tsNode_ = std::make_shared(customNodeHandle_); tsNode_->MarkReleaseHandle(false); - subContainerNode_ = std::make_shared(); - - containerNode_->AddChild(tsNode_.get()); - containerNode_->AddChild(subContainerNode_.get()); - containerNode_->SetClip(true); - subContainerNode_->SetWidthPercent(1.f); - subContainerNode_->SetHeightPercent(1.f); - subContainerNode_->SetHitTestMode(ARKUI_HIT_TEST_MODE_NONE); + contentNode_ = std::make_shared(); + contentNode_->SetWidthPercent(1.f); + contentNode_->SetHeightPercent(1.f); + contentNode_->SetHitTestMode(ARKUI_HIT_TEST_MODE_NONE); + if (contentHandle_) { + OH_ArkUI_NodeContent_RegisterCallback(contentHandle_, nullptr); + OH_ArkUI_NodeContent_AddNode(contentHandle_, contentNode_->GetArkUINodeHandle()); + } } void CustomTsView::DestroyArkUINodeImpl() { - containerNode_ = nullptr; + if (contentHandle_) { + OH_ArkUI_NodeContent_RemoveNode(contentHandle_, contentNode_->GetArkUINodeHandle()); + } tsNode_ = nullptr; - subContainerNode_ = nullptr; + contentNode_ = nullptr; } bool CustomTsView::SetPropImpl(const std::string &propKey, const HippyValue &propValue) { @@ -99,12 +98,12 @@ void CustomTsView::OnChildRemoved(std::shared_ptr const &childView, in void CustomTsView::OnChildInsertedImpl(std::shared_ptr const &childView, int32_t index) { BaseView::OnChildInsertedImpl(childView, index); - subContainerNode_->InsertChild(childView->GetLocalRootArkUINode(), index); + contentNode_->InsertChild(childView->GetLocalRootArkUINode(), index); } void CustomTsView::OnChildRemovedImpl(std::shared_ptr const &childView, int32_t index) { BaseView::OnChildRemovedImpl(childView, index); - subContainerNode_->RemoveChild(childView->GetLocalRootArkUINode()); + contentNode_->RemoveChild(childView->GetLocalRootArkUINode()); } void CustomTsView::OnCustomTsViewChildInserted(uint32_t tag, std::shared_ptr const &childView, int32_t index) { diff --git a/framework/ohos/src/main/cpp/impl/renderer/native/src/uimanager/hr_view_manager.cc b/framework/ohos/src/main/cpp/impl/renderer/native/src/uimanager/hr_view_manager.cc index 68285998585..674021e3578 100644 --- a/framework/ohos/src/main/cpp/impl/renderer/native/src/uimanager/hr_view_manager.cc +++ b/framework/ohos/src/main/cpp/impl/renderer/native/src/uimanager/hr_view_manager.cc @@ -545,7 +545,7 @@ HRRect HRViewManager::GetViewFrameInRoot(uint32_t node_id) { } void HRViewManager::AddBizViewInRoot(uint32_t biz_view_id, ArkUI_NodeHandle node_handle, const HRPosition &position) { - auto view = std::make_shared(ctx_, node_handle); + auto view = std::make_shared(ctx_, node_handle, nullptr); view->Init(); view->SetTag(biz_view_id); view->SetViewType("BizView"); @@ -589,24 +589,33 @@ std::shared_ptr HRViewManager::CreateCustomTsRenderView(uint32_t tag, }; auto delegateObject = arkTs.GetObject(ts_render_provider_ref_); - napi_value tsNode = delegateObject.Call("createRenderViewForCApi", args); + napi_value nodeResult = delegateObject.Call("createRenderViewForCApi", args); - napi_valuetype type = arkTs.GetType(tsNode); - if (type == napi_null) { - FOOTSTONE_LOG(ERROR) << "create ts view error, tsNode null"; + napi_valuetype type = arkTs.GetType(nodeResult); + if (type != napi_object) { + FOOTSTONE_LOG(ERROR) << "create ts view error, nodeResult not object"; return nullptr; } - + + napi_value frameNode = arkTs.GetObjectProperty(nodeResult, "frameNode"); ArkUI_NodeHandle nodeHandle = nullptr; - auto status = OH_ArkUI_GetNodeHandleFromNapiValue(ts_env_, tsNode, &nodeHandle); + auto status = OH_ArkUI_GetNodeHandleFromNapiValue(ts_env_, frameNode, &nodeHandle); if (status != ARKUI_ERROR_CODE_NO_ERROR) { FOOTSTONE_LOG(ERROR) << "create ts view error, nodeHandle fail, status: " << status << ", nodeHandle: " << nodeHandle; return nullptr; } + napi_value childSlot = arkTs.GetObjectProperty(nodeResult, "childSlot"); + ArkUI_NodeContentHandle contentHandle = nullptr; + status = OH_ArkUI_GetNodeContentFromNapiValue(ts_env_, childSlot, &contentHandle); + if (status != ARKUI_ERROR_CODE_NO_ERROR) { + FOOTSTONE_LOG(ERROR) << "create ts view error, contentHandle fail, status: " << status << ", contentHandle: " << contentHandle; + return nullptr; + } + napi_close_handle_scope(ts_env_, scope); - auto view = std::make_shared(ctx_, nodeHandle); + auto view = std::make_shared(ctx_, nodeHandle, contentHandle); view->Init(); view->SetTag(tag); view->SetViewType(view_name); diff --git a/framework/ohos/src/main/ets/renderer_native/NativeRenderBuilderForCApi.ets b/framework/ohos/src/main/ets/renderer_native/NativeRenderBuilderForCApi.ets index ed1fc7b3452..d63f1d09c72 100644 --- a/framework/ohos/src/main/ets/renderer_native/NativeRenderBuilderForCApi.ets +++ b/framework/ohos/src/main/ets/renderer_native/NativeRenderBuilderForCApi.ets @@ -20,6 +20,7 @@ import { HippyAny, HippyMap } from '../support/common/HippyTypes' import HippyRenderBaseView from './components/base/HippyRenderBaseView' import { HRWeb, HRWebView } from './components/web/HRWebView' +import { NodeContent } from '@kit.ArkUI' export interface CreateRenderViewParamsForCApi { rootTag: number @@ -27,6 +28,11 @@ export interface CreateRenderViewParamsForCApi { viewName: string } +export interface CreateRenderViewResultForCApi { + frameNode?: FrameNode + childSlot?: NodeContent +} + export interface RemoveRenderViewParamsForCApi { rootTag: number tag: number diff --git a/framework/ohos/src/main/ets/renderer_native/NativeRenderImpl.ets b/framework/ohos/src/main/ets/renderer_native/NativeRenderImpl.ets index 46366ceceea..45d3f107af8 100644 --- a/framework/ohos/src/main/ets/renderer_native/NativeRenderImpl.ets +++ b/framework/ohos/src/main/ets/renderer_native/NativeRenderImpl.ets @@ -33,6 +33,7 @@ import { buildHippyRenderViewForCApi, CallRenderViewMethodParamsForCApi, CreateRenderViewParamsForCApi, + CreateRenderViewResultForCApi, OnChildInsertedParamsForCApi, OnChildRemovedParamsForCApi, RemoveRenderViewParamsForCApi, @@ -65,7 +66,7 @@ import { HRDisplaySyncUtils } from './utils/HRDisplaySyncUtils' import { HRMeasureResult } from './utils/HRMeasure' import { HRPosition, HRRect, HRSize } from './utils/HRTypes' import { HRValueUtils } from './utils/HRValueUtils' -import { BuilderNode, FrameNode } from '@kit.ArkUI' +import { BuilderNode, FrameNode, NodeContent } from '@kit.ArkUI' import HippyRenderBaseView from './components/base/HippyRenderBaseView' import { HippyRootView } from '.' import { @@ -642,7 +643,7 @@ key1 value1 } // for c-api - createRenderViewForCApi(params: CreateRenderViewParamsForCApi): FrameNode | null { + createRenderViewForCApi(params: CreateRenderViewParamsForCApi): CreateRenderViewResultForCApi | null { let viewManager = this.renderManager.getViewManager(params.rootTag) if (!viewManager) { return null @@ -655,7 +656,8 @@ key1 value1 let context = AppStorage.get('UIContextForHippy'); - let view = viewManager.createRenderViewForCApi(params.tag, params.viewName) + let childSlot: NodeContent = new NodeContent() + let view = viewManager.createRenderViewForCApi(params.tag, params.viewName, childSlot) if (!view) { return null } @@ -666,7 +668,7 @@ key1 value1 let builderNodeManger = this.renderManager.getBuilerNodeManager(params.rootTag) builderNodeManger?.addCustomViewBuilderNode(params.tag, builderNode) - return builderNode.getFrameNode()!; + return { frameNode: builderNode.getFrameNode()!, childSlot: childSlot } } // for c-api diff --git a/framework/ohos/src/main/ets/renderer_native/NativeRenderProvider.ets b/framework/ohos/src/main/ets/renderer_native/NativeRenderProvider.ets index 0dc7c4ca71f..22d9c076205 100644 --- a/framework/ohos/src/main/ets/renderer_native/NativeRenderProvider.ets +++ b/framework/ohos/src/main/ets/renderer_native/NativeRenderProvider.ets @@ -31,6 +31,7 @@ import { HRRenderViewCreator } from './components/HippyRenderRegisterMap'; import { CallRenderViewMethodParamsForCApi, CreateRenderViewParamsForCApi, + CreateRenderViewResultForCApi, OnChildInsertedParamsForCApi, OnChildRemovedParamsForCApi, RemoveRenderViewParamsForCApi, @@ -301,7 +302,7 @@ export class NativeRenderProvider { } // for c-api - createRenderViewForCApi(params: CreateRenderViewParamsForCApi): FrameNode | null { + createRenderViewForCApi(params: CreateRenderViewParamsForCApi): CreateRenderViewResultForCApi | null { return this.renderImpl.createRenderViewForCApi(params) } diff --git a/framework/ohos/src/main/ets/renderer_native/components/custom/HippyCustomComponentView.ets b/framework/ohos/src/main/ets/renderer_native/components/custom/HippyCustomComponentView.ets index e9bff5a6e8b..890621cd79b 100644 --- a/framework/ohos/src/main/ets/renderer_native/components/custom/HippyCustomComponentView.ets +++ b/framework/ohos/src/main/ets/renderer_native/components/custom/HippyCustomComponentView.ets @@ -22,8 +22,11 @@ import { NativeRenderContext } from '../../NativeRenderContext' import { HRMeasureMode, HRMeasureResult } from '../../utils/HRMeasure' import { HRPadding, HRRect } from '../../utils/HRTypes' import HippyRenderBaseView from '../base/HippyRenderBaseView' +import { NodeContent } from '@kit.ArkUI' export class HippyCustomComponentView extends HippyRenderBaseView { + childSlot: NodeContent | null = null + constructor(ctx: NativeRenderContext) { super(ctx) } @@ -32,19 +35,6 @@ export class HippyCustomComponentView extends HippyRenderBaseView { return super.setProp(propKey, propValue) } - updateRenderViewFrame(frame: HRRect, padding: HRPadding | null): void { - // For c api, the position is used by container node. - if (this.ctx.getNativeRender().isEnableArkCApi()) { - this.cssPositionX = 0 - this.cssPositionY = 0 - } else { - this.cssPositionX = frame.x - this.cssPositionY = frame.y - } - this.cssWidth = frame.width - this.cssHeight = frame.height - } - call(method: string, params: Array, callback: HippyRenderCallback | null): void { } diff --git a/framework/ohos/src/main/ets/renderer_native/components/web/HRWebView.ets b/framework/ohos/src/main/ets/renderer_native/components/web/HRWebView.ets index 9e6369ba79f..b3808511cbc 100644 --- a/framework/ohos/src/main/ets/renderer_native/components/web/HRWebView.ets +++ b/framework/ohos/src/main/ets/renderer_native/components/web/HRWebView.ets @@ -126,19 +126,6 @@ export class HRWebView extends HippyRenderBaseView { } } - protected updateRenderViewFrame(frame: HRRect, padding: HRPadding | null): void { - // For c api, web view is a custom ts view, the position is used by container node. - if (this.ctx.getNativeRender().isEnableArkCApi()) { - this.cssPositionX = 0 - this.cssPositionY = 0 - } else { - this.cssPositionX = frame.x - this.cssPositionY = frame.y - } - this.cssWidth = frame.width - this.cssHeight = frame.height - } - call(method: string, params: Array, callback: HippyRenderCallback | null): void { switch (method) { case "loadUrl": diff --git a/framework/ohos/src/main/ets/renderer_native/uimanager/HRViewManager.ets b/framework/ohos/src/main/ets/renderer_native/uimanager/HRViewManager.ets index 072c7113083..06014e2f183 100644 --- a/framework/ohos/src/main/ets/renderer_native/uimanager/HRViewManager.ets +++ b/framework/ohos/src/main/ets/renderer_native/uimanager/HRViewManager.ets @@ -38,6 +38,7 @@ import { HRCreateMutation, HRUpdateEventListenerMutation, HRUpdateLayoutMutation, HRUpdateMutation } from './HRMutation' +import { NodeContent } from '@kit.ArkUI' export type HippyEndBatchCallback = () => void @@ -292,7 +293,7 @@ export class HRViewManager { } // for c-api - createRenderViewForCApi(tag: number, viewName: string): HippyRenderBaseView | null { + createRenderViewForCApi(tag: number, viewName: string, childSlot: NodeContent): HippyRenderBaseView | null { let renderView: HippyRenderBaseView | null = null if (viewName == "WebView") { renderView = new HRWebView(this.ctx); @@ -302,6 +303,9 @@ export class HRViewManager { let creator = customCreatorMap.get(viewName) if (creator) { renderView = creator(this.ctx) + if (renderView) { + (renderView as HippyCustomComponentView).childSlot = childSlot + } } } }