设置通用布局属性
========

从API version 12开始，ArkUI在NDK中提供了一组通用布局属性，可以控制组件的尺寸、位置、边框等布局行为。

本文选取了尺寸设置（[width](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#width)、[height](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#height)、[size](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#size)、[aspectRatio](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-layout-constraints#aspectratio)、[padding](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#padding)、[margin](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#margin)、[layoutWeight](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#layoutweight)）、位置设置（[position](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-location#position)、[offset](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-location#offset)）、边框设置（[borderWidth](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#borderwidth)、[borderColor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#bordercolor)、[borderStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#borderstyle)、[borderRadius](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#borderradius)）三个典型场景，提供NDK下通用布局属性接入的开发指导，对应属性设置和参数类型枚举可参考[ArkUI\_NodeType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-node-h#arkui_nodetype)。

本示例仅展示核心功能代码，完整示例请参考[NDKLayoutSample](https://gitcode.com/HarmonyOS_Samples/guide-snippets/tree/master/ArkUISample/NDKLayoutSample)；实现前需要先接入ArkTS页面，具体接入方式可参考[接入ArkTS页面](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ndk-access-the-arkts-page)。

#### 设置组件尺寸

NDK通用布局属性的推荐使用方式是：先在节点类中封装属性设置方法，再在具体组件上调用。以下示例封装了一组固定尺寸与宽高比属性。

void SetWidth(float width)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = width}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_WIDTH, &item);
}
void SetPercentWidth(float percent)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = percent}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_WIDTH\_PERCENT, &item);
}
void SetHeight(float height)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = height}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_HEIGHT, &item);
}
void SetPercentHeight(float percent)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = percent}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_HEIGHT\_PERCENT, &item);
}
void SetSize(float width, float height)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = width}, {.f32 = height}};
    ArkUI\_AttributeItem item = {value, 2};
    nativeModule\_->setAttribute(handle\_, NODE\_SIZE, &item);
}

void SetAspectRatio(float ratio)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = ratio}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_ASPECT\_RATIO, &item);
}

在组件上组合使用这些方法，可以观察到固定尺寸、百分比尺寸和宽高比生效。

inline std::shared\_ptr<ArkUITextNode> CreateFixedSizeItem()
{
    auto fixedItem = CreateDemoItem("NODE\_SIZE\\n112 x 68vp", SIZE\_ITEM\_BLUE);
    fixedItem->SetSize(FIXED\_ITEM\_WIDTH, FIXED\_ITEM\_HEIGHT);
    fixedItem->SetMargin(0.0F, SAMPLE\_GAP, 0.0F, 0.0F);
    return fixedItem;
}

inline std::shared\_ptr<ArkUITextNode> CreateAspectRatioItem()
{
    auto ratioItem = CreateDemoItem("height=64\\naspectRatio=2.0", SIZE\_ITEM\_GREEN);
    ratioItem->SetHeight(RATIO\_ITEM\_HEIGHT);
    ratioItem->SetAspectRatio(RATIO\_VALUE);
    ratioItem->SetMargin(0.0F, SAMPLE\_GAP, 0.0F, 0.0F);
    return ratioItem;
}

inline std::shared\_ptr<ArkUITextNode> CreatePercentWidthItem()
{
    auto percentItem = CreateDemoItem("width=30%", SIZE\_ITEM\_ORANGE);
    percentItem->SetPercentWidth(PERCENT\_WIDTH\_VALUE);
    percentItem->SetHeight(RATIO\_ITEM\_HEIGHT);
    return percentItem;
}

SetSize()同时写入宽和高，适合固定尺寸组件；SetPercentWidth()通过入参常量PERCENT\_WIDTH\_VALUE配置组件宽度为父容器宽度的30%；SetAspectRatio()通过配置固定宽高比，从显式设置的组件高度自动推导对应的宽度。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e7/v3/IETX9MqhTESyzbl4fGGMIw/zh-cn_image_0000002664207837.jpg?HW-CC-KV=V1&HW-CC-Date=20260709T132314Z&HW-CC-Expire=86400&HW-CC-Sign=122D9F68857B03D4B2B681705529A2CBDD0A5AA2B37985F8108D0AF5469DB6E8)

通常，还需要通过padding和margin控制内外边距、调节组件尺寸，以实现良好的间距效果。

void SetPadding(float padding)
{
  ArkUI\_NumberValue value\[\] = {{.f32 = padding}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_PADDING, &item);
}
void SetPadding(float top, float right, float bottom, float left)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = top}, {.f32 = right}, {.f32 = bottom}, {.f32 = left}};
    ArkUI\_AttributeItem item = {value, 4};
    nativeModule\_->setAttribute(handle\_, NODE\_PADDING, &item);
}
void SetPercentPadding(float percent)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = percent}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_PADDING\_PERCENT, &item);
}
void SetPercentPadding(float top, float right, float bottom, float left)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = top}, {.f32 = right}, {.f32 = bottom}, {.f32 = left}};
    ArkUI\_AttributeItem item = {value, 4};
    nativeModule\_->setAttribute(handle\_, NODE\_PADDING\_PERCENT, &item);
}
void SetMargin(float margin)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = margin}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_MARGIN, &item);
}
void SetMargin(float top, float right, float bottom, float left)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = top}, {.f32 = right}, {.f32 = bottom}, {.f32 = left}};
    ArkUI\_AttributeItem item = {value, 4};
    nativeModule\_->setAttribute(handle\_, NODE\_MARGIN, &item);
}
void SetPercentMargin(float percent)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = percent}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_MARGIN\_PERCENT, &item);
}
void SetPercentMargin(float top, float right, float bottom, float left)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = top}, {.f32 = right}, {.f32 = bottom}, {.f32 = left}};
    ArkUI\_AttributeItem item = {value, 4};
    nativeModule\_->setAttribute(handle\_, NODE\_MARGIN\_PERCENT, &item);
}

inline std::shared\_ptr<ArkUITextNode> CreatePercentWidthPaddingItem()
{
    auto inner = CreateDemoItem("内容区", PADDING\_ITEM\_BLUE);
    inner->SetPercentWidth(FULL\_SIZE);
    return inner;
}

inline std::shared\_ptr<ArkUIColumnNode> CreatePaddingHost()
{
    auto paddingHost = std::make\_shared<ArkUIColumnNode>();
    paddingHost->SetPercentWidth(FULL\_SIZE);
    paddingHost->SetHeight(SPACING\_PADDING\_HOST\_HEIGHT);
    paddingHost->SetBackgroundColor(SURFACE\_BACKGROUND\_COLOR);
    paddingHost->SetPadding(PADDING\_TOP, PADDING\_RIGHT, PADDING\_TOP, PADDING\_RIGHT);
    paddingHost->SetMargin(0.0F, 0.0F, CARD\_MARGIN\_BOTTOM, 0.0F);
    paddingHost->AddChild(CreatePercentWidthPaddingItem());
    return paddingHost;
}

inline std::shared\_ptr<ArkUITextNode> CreateMarginItem(const std::string &text, uint32\_t color, bool addSpacing = false)
{
    auto item = CreateDemoItem(text, color);
    item->SetWidth(SMALL\_ITEM\_WIDTH);
    if (addSpacing) { item->SetMargin(0.0F, SAMPLE\_GAP, 0.0F, 0.0F); }
    return item;
}

内边距padding用于控制组件内容区与边缘之间的留白，外边距margin用于控制组件与父容器边缘的留白间距。如果需要按父容器比例设置间距，则可使用[ArkUI\_NodeType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-node-h#arkui_nodetype)中NODE\_PADDING\_PERCENT和NODE\_MARGIN\_PERCENT对应的方法。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/9e/v3/PqQmFx4oTreggLOtzy2CgA/zh-cn_image_0000002664327897.jpg?HW-CC-KV=V1&HW-CC-Date=20260709T132314Z&HW-CC-Expire=86400&HW-CC-Sign=2ED617A9CC4DD811575FACA4B4B489633716CDB36BCA337B9B316F11AC9B069B)

#### 使用位置属性

当尺寸和间距已经确定后，如果需要进一步调整组件摆放位置，可以使用[position](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-location#position)和[offset](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-location#offset)。两者都会改变组件的显示位置，但含义不同。position表示相对父容器进行定位，offset表示在原有布局结果上发生偏移。

void SetPosition(float x, float y)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = x}, {.f32 = y}};
    ArkUI\_AttributeItem item = {value, 2};
    nativeModule\_->setAttribute(handle\_, NODE\_POSITION, &item);
}

void SetOffset(float x, float y)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = x}, {.f32 = y}};
    ArkUI\_AttributeItem item = {value, 2};
    nativeModule\_->setAttribute(handle\_, NODE\_OFFSET, &item);
}

分别将这两个属性施加在不同组件上对比。

inline std::shared\_ptr<ArkUITextNode> CreatePositionedItem()
{
    auto positioned = CreateDemoItem("position(20, 18)", POSITION\_ITEM\_ORANGE);
    positioned->SetWidth(LARGE\_ITEM\_WIDTH);
    positioned->SetPosition(POSITION\_X, POSITION\_Y);
    return positioned;
}

inline std::shared\_ptr<ArkUITextNode> CreateOffsetItem()
{
    auto offset = CreateDemoItem("offset(110, 80)", POSITION\_ITEM\_BLUE);
    offset->SetWidth(LARGE\_ITEM\_WIDTH);
    offset->SetMargin(OFFSET\_MARGIN\_TOP, 0.0F, 0.0F, 0.0F);
    offset->SetOffset(OFFSET\_X, POSITION\_Y);
    return offset;
}

可以看到两种效果：position直接给出目标位置，offset则保留原有占位关系，再向目标方向偏移。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/4c/v3/1jQO3wDnSsqI3EGF_GS2JA/zh-cn_image_0000002633848788.jpg?HW-CC-KV=V1&HW-CC-Date=20260709T132314Z&HW-CC-Expire=86400&HW-CC-Sign=F4F6215972E85AB7E5D66E362DBD1CD09E59B388C619F3CE7AD4B34CB439BBA5)

#### 使用边框属性

边框属性在NDK中的使用方式与上文一致，同样是先封装方法，再在具体组件上组合调用。方法封装如下。

void SetBorderWidth(float width)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = width}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_BORDER\_WIDTH, &item);
}
void SetBorderWidth(float top, float right, float bottom, float left)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = top}, {.f32 = right}, {.f32 = bottom}, {.f32 = left}};
    ArkUI\_AttributeItem item = {value, 4};
    nativeModule\_->setAttribute(handle\_, NODE\_BORDER\_WIDTH, &item);
}
void SetBorderRadius(float radius)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = radius}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_BORDER\_RADIUS, &item);
}
void SetBorderRadius(float topLeft, float topRight, float bottomLeft, float bottomRight)
{
    ArkUI\_NumberValue value\[\] = {{.f32 = topLeft}, {.f32 = topRight}, {.f32 = bottomLeft}, {.f32 = bottomRight}};
    ArkUI\_AttributeItem item = {value, 4};
    nativeModule\_->setAttribute(handle\_, NODE\_BORDER\_RADIUS, &item);
}
void SetBorderColor(uint32\_t color)
{
    ArkUI\_NumberValue value\[\] = {{.u32 = color}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_BORDER\_COLOR, &item);
}
void SetBorderColor(uint32\_t top, uint32\_t right, uint32\_t bottom, uint32\_t left)
{
    ArkUI\_NumberValue value\[\] = {{.u32 = top}, {.u32 = right}, {.u32 = bottom}, {.u32 = left}};
    ArkUI\_AttributeItem item = {value, 4};
    nativeModule\_->setAttribute(handle\_, NODE\_BORDER\_COLOR, &item);
}
void SetBorderStyle(ArkUI\_BorderStyle style)
{
    ArkUI\_NumberValue value\[\] = {{.i32 = style}};
    ArkUI\_AttributeItem item = {value, 1};
    nativeModule\_->setAttribute(handle\_, NODE\_BORDER\_STYLE, &item);
}
void SetBorderStyle(
  ArkUI\_BorderStyle top, ArkUI\_BorderStyle right, ArkUI\_BorderStyle bottom, ArkUI\_BorderStyle left)
{
    ArkUI\_NumberValue value\[\] = {{.i32 = top}, {.i32 = right}, {.i32 = bottom}, {.i32 = left}};
    ArkUI\_AttributeItem item = {value, 4};
    nativeModule\_->setAttribute(handle\_, NODE\_BORDER\_STYLE, &item);
}

当组件已经具备尺寸和间距后，可以继续叠加这些边框属性，构建轮廓和视觉分隔的效果。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f6/v3/mf6IP4pqSUSfDYWYjy4I2g/zh-cn_image_0000002634008692.jpg?HW-CC-KV=V1&HW-CC-Date=20260709T132314Z&HW-CC-Expire=86400&HW-CC-Sign=A18C3A2782978A572678C5917ED4DE1BC89FC176FFBA4EEE73F5B8E245C0F559)