HarmonyOS鸿蒙Next中如何实现自定义容器组件

HarmonyOS鸿蒙Next中如何实现自定义容器组件 我实现了一个类似于控制中心顶部实时模糊的组件,我希望所有的页面都可以直接调用这个组件,然后通过@Builder将内容插入,但是现在出现了一个问题,我应该如何将这个组件直接放在build()定义中?

顶部实时模糊组件代码:

[@Component](/user/Component)
export struct Page {
  @BuilderParam @Require column:()=>void=emptyBuilderFunction;
  @BuilderParam @Require navBar:()=>void=emptyBuilderFunction;
  build() {
    Stack() {
      Scroll() {
        Column({ space: 8 }) {
          this.column()
        }
        .padding({top: 60, left: 16, right: 16, bottom: 0})

      }
      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM])
      .edgeEffect(EdgeEffect.Spring)
      .height("100%")
      .align(Alignment.TopStart)

      // 导航栏
      this.navBar()
    }
    .width('100%')
    .alignContent(Alignment.TopStart)
  }
}

我在@Entry的组件中调用:

[@Entry](/user/Entry)
[@Component](/user/Component)
struct Second {

  [@Builder](/user/Builder)
  navBar() {
    Text("navBar")
  }

  [@Builder](/user/Builder)
  column() {
    Text("content")
  }
  
  build() {
      Page({
        navBar: () => {
          this.navBar()
        },
        column: () => {
          this.column()
        },
      })
  }

但问题是这是不被允许的,因为自定义的Page组件不是容器组件,事实上可以通过用Column组件包裹Page来绕过限制,但是是否有方案可以实现自定义容器组件?

参考next文档-自定义组件

@Entry装饰的自定义组件,其build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。

@Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容器组件,其中ForEach禁止作为根节点。


更多关于HarmonyOS鸿蒙Next中如何实现自定义容器组件的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

除了自定义组件根节点加一个容器组件外,没有其他的方案

更多关于HarmonyOS鸿蒙Next中如何实现自定义容器组件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中实现自定义容器组件,主要涉及以下几个步骤:

  1. 定义组件类:创建一个新的类,继承自ComponentComponentContainerComponentContainer是容器组件的基类,适合用于包含其他组件的场景。

  2. 重写生命周期方法:在自定义组件类中,重写onAttachedToWindowonDetachedFromWindow等生命周期方法,以管理组件的生命周期。

  3. 布局管理:如果组件需要管理子组件的布局,可以重写onMeasureonLayout方法。onMeasure用于测量组件及其子组件的大小,onLayout用于确定子组件的位置。

  4. 事件处理:重写onTouchEvent等方法以处理用户交互事件。

  5. 样式与属性:通过Component.AttrSet获取XML中定义的属性,并根据这些属性配置组件的外观和行为。

  6. 使用自定义组件:在XML布局文件中使用自定义组件时,需要指定完整的包名和类名。

示例代码:

import { Component, ComponentContainer, AttrSet } from '@ohos.arkui';

class MyCustomContainer extends ComponentContainer {
    constructor(context: Context, attrs?: AttrSet) {
        super(context, attrs);
        // 初始化代码
    }

    onAttachedToWindow() {
        super.onAttachedToWindow();
        // 组件附加到窗口时的处理
    }

    onDetachedFromWindow() {
        super.onDetachedFromWindow();
        // 组件从窗口分离时的处理
    }

    onMeasure(widthMeasureSpec: number, heightMeasureSpec: number) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 自定义测量逻辑
    }

    onLayout(changed: boolean, left: number, top: number, right: number, bottom: number) {
        super.onLayout(changed, left, top, right, bottom);
        // 自定义布局逻辑
    }

    onTouchEvent(event: TouchEvent): boolean {
        // 处理触摸事件
        return super.onTouchEvent(event);
    }
}

在XML中使用:

<com.example.MyCustomContainer
    ohos:width="match_parent"
    ohos:height="match_parent">
    <!-- 子组件 -->
</com.example.MyCustomContainer>

在HarmonyOS鸿蒙Next中,实现自定义容器组件可以通过继承ComponentComponentContainer类,并重写相关方法来实现。以下是一个简单的步骤:

  1. 创建自定义组件类:

    public class CustomContainer extends ComponentContainer {
        public CustomContainer(Context context) {
            super(context);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // 自定义测量逻辑
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            // 自定义布局逻辑
            super.onLayout(changed, l, t, r, b);
        }
    }
    
  2. 在布局文件中使用:

    <com.example.CustomContainer
        ohos:id="$+id/custom_container"
        ohos:width="match_parent"
        ohos:height="match_parent">
        <!-- 添加子组件 -->
    </com.example.CustomContainer>
    
  3. 在Java代码中操作:

    CustomContainer customContainer = (CustomContainer) findComponentById(ResourceTable.Id_custom_container);
    // 添加或操作子组件
    
回到顶部