容器断点 (ContainerReader)
======================

容器断点组件[ContainerReader](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader)是ArkUI提供的一种响应式布局解决方案，从API版本26.0.0开始，允许开发者基于容器尺寸而非窗口尺寸实现自适应布局。与传统的窗口断点相比，容器断点提供了更细粒度的布局控制能力，使得组件能够在不同的容器尺寸下呈现不同的布局效果。

ContainerReader在实际开发中常用于[Flex](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-flex)、[Row](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-row)或[Column](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-column)容器内部、[Navigation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation)以及[自定义组件](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-create-custom-components)内部场景，提供实时尺寸获取、断点值获取和自定义断点阈值核心功能。

#### 能力范围

ContainerReader提供以下关键能力。

*   **容器级尺寸感知**：基于组件自身实际尺寸确定断点值，而非窗口尺寸。适用于组件级响应式布局、嵌套布局场景和可复用组件开发。
*   **双向绑定实时获取**：通过状态变量实时获取容器尺寸和断点信息。
*   **宽度/高度双模式**：同时支持宽度断点和高度断点，满足不同维度的自适应需求。
*   **自定义断点阈值**：通过[breakpointConfig](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader#breakpointconfig)属性灵活配置不同尺寸区间对应的布局策略。

#### 布局规格

从API版本26.0.0开始，[ContainerReader](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader)组件在不同父容器类型下的布局规格如下。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/47/v3/D6Z7hxW2RDCNulnW5Es1_A/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=55102BF1E03AE0E55E082BC9A5E8CAC4EB573F8FF4EB12E4D85A1EFCBCC3EA67)

*   当父容器为Flex组件、Row组件或Column组件时，ContainerReader会占满父容器剩余空间，Flex的弹性特性生效优先级不变。
*   当父容器为其他容器类型时，ContainerReader会撑满父容器。
*   ContainerReader的尺寸由父容器和自身布局确定，不受子组件影响。

| 父容器类型 | 无兄弟节点 | 有兄弟节点 |
| :-- | :-- | :-- |
| Flex、Row、Column | 撑满父容器。 | 撑满父容器剩余空间。 |
| 其他类型组件 | 撑满父组件。 | 撑满父组件。 |

[ContainerReader](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader)作为子组件时，其尺寸由父容器决定。当父容器为Flex、Row或Column时，ContainerReader会根据父容器的布局方向自动撑满父容器剩余空间。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f2/v3/2tqdT5UQRMyDSsp5vZ-sLw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=7B36CF38B0F4B6DB5E1100F224D8DD0EDC9D63B5FD3E7EA9FDA1EE30F257DC03)

使用ContainerReader需要同时导入ContainerReaderAttribute，否则会导致编译报错。

import {ContainerReader, ContainerReaderAttribute, Size} from '@kit.ArkUI';
@Entry
@Component
struct Example {
  @State containerSize: Size = { width: 0, height: 0 };
  @State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
  build() {
    Flex({ direction: FlexDirection.Row }) {
      ContainerReader({
        size: this.containerSize!!,
        widthBreakpoint: this.widthBp!!
      }) {
        Column() {
          Text('Adaptive Content')
        }
        .width('100%')
        .height('100%')
      }
      .backgroundColor('#F7F7F7')
    }
    .padding(10)
    .width('100%')
    .height(200)
    .backgroundColor('#D5D5D5')
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/af/v3/aIeD_cEgQvS_-lW7jfclDQ/zh-cn_image_0000002634008318.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=4962B74741456BBEB4762F6F2272E1DF9EC7BBCD7A4944825147FEC26EA5989B)

[ContainerReader](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader)作为Flex、Row或Column的子组件使用时，会优先为非ContainerReader类型的子组件测算尺寸，再结合父容器剩余空间与开发者设置为ContainerReader组件分配空间。这在固定内容与自适应内容并存的场景中较为适用。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b8/v3/XzkzpJVdRUWtEJkxkQjOUw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=EAC929481A6D50E34F7E5862071053B966B273C7A22B527F62FE85C4DC19FFFF)

使用ContainerReader需要同时导入ContainerReaderAttribute，否则会导致编译报错。

import {ContainerReader, ContainerReaderAttribute, Size} from '@kit.ArkUI';
@Entry
@Component
struct Example {
  @State containerSize: Size = { width: 0, height: 0 };
  @State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
  build() {
    Flex({ direction: FlexDirection.Row }) {
      Column() {
        Text('Text')
          .width(100)
          .height('100%')
      }
      .width(100)
      .height('100%')
      .backgroundColor('#D5D5D5')
      ContainerReader({
        size: this.containerSize!!,
        widthBreakpoint: this.widthBp!!
      }) {
        Column() {
          Text('ContainerReader')
        }
        .width('100%')
        .height('100%')
        .justifyContent(FlexAlign.Center)
      }
      .backgroundColor('#F7F7F7')
    }
    .width('100%')
    .height(300)
    .backgroundColor('#F0FAFF')
    .padding(10)
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/c9/v3/bWWpP2aTR4-rzv_N4G-sLg/zh-cn_image_0000002664207467.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=D04477F1C113ED26E6D4528EDE57C3ACC18B03FB1BF68BA608C8BD0F98715C6D)

当Flex、Row或Column容器中有多个[ContainerReader](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader)子组件时，按开发者书写顺序第一个ContainerReader会占满剩余空间，此时其余ContainerReader组件的主轴大小为0。但开发者可以通过layoutWeight属性使多个ContainerReader平分剩余空间。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/49/v3/3V2dodEHQoKAJC_zbM9-bw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=6CEBB534AFFB396230A297F67A667D5F7D84E99A3684AF54967D9EF1D9F1A95A)

使用ContainerReader需要同时导入ContainerReaderAttribute，否则会导致编译报错。

import {ContainerReader, ContainerReaderAttribute, Size} from '@kit.ArkUI';
@Entry
@Component
struct Example {
  @State containerSize: Size = { width: 0, height: 0 };
  @State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
  @State containerSize1: Size = { width: 0, height: 0 };
  @State widthBp1: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
  build() {
    Flex({ direction: FlexDirection.Row }) {
      // 固定宽度的兄弟组件，优先测算
      Column() {
        Text('Text')
          .width(80)
          .height('100%')

      }
      .width(80)
      .height('100%')
      .backgroundColor('#D5D5D5')

      // 第一个ContainerReader，通过layoutWeight(1)分配1/2剩余空间
      ContainerReader({
        size: this.containerSize!!,
        widthBreakpoint: this.widthBp!!
      }) {
        Column() {
          Text('ContainerReader1')
        }
        .width('100%')
        .height('100%')
        .justifyContent(FlexAlign.Center)
      }
      .layoutWeight(1)
      .backgroundColor('#F7F7F7')

      // 第二个ContainerReader，同样layoutWeight(1)分配1/2剩余空间
      ContainerReader({
        size: this.containerSize1!!,
        widthBreakpoint: this.widthBp1!!
      }) {
        Column() {
          Text('ContainerReader2')
        }
        .width('100%')
        .height('100%')
        .justifyContent(FlexAlign.Center)
      }
      .layoutWeight(1)
      .backgroundColor('#707070')
    }
    .width('100%')
    .height(300)
    .backgroundColor('#F0FAFF')
    .padding(10)
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ec/v3/UUUUoPpkQdCMzM661tVyMg/zh-cn_image_0000002664327527.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=428F365D041D7D767B6F5A9FFD3D843A637E162931A2B47D99A95EE8F2F40E12)

#### 约束与限制

**状态变量要求**

ContainerReaderInfo的所有参数都必须通过状态变量进行双向绑定。

// 正确用法 - 使用!!触发双向绑定
@State containerSize: Size = { width: 0, height: 0 };
@State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;

ContainerReader({
  size: this.containerSize!!,
  widthBreakpoint: this.widthBp!!
})

// 错误用法1 - 未使用!!后缀，双向绑定不生效
ContainerReader({
  size: this.containerSize,
  widthBreakpoint: this.widthBp
})

// 错误用法2 - 使用非状态变量
const containerSize: Size = { width: 0, height: 0 };

ContainerReader({
  size: containerSize,  // 必须是@State修饰的状态变量
  widthBreakpoint: WidthBreakpoint.WIDTH\_MD
})

**尺寸计算时机**

[ContainerReader](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader)的尺寸由父容器和自身布局确定，不受子组件影响。在ContainerReader组件尺寸测算时，先根据父组件和自身设置确认自身尺寸，然后再做子组件的展开尺寸测算。为防止在节点未尺寸测算前的生命周期中使用ContainerReader组件双向绑定的size状态变量，需要给双向绑定状态变量一个初始值。

因此请确保，父容器有明确尺寸，含有ContainerReader组件的父容器不应依赖子节点确认自身大小，ContainerReader组件不依赖自身子节点大小确认尺寸。

#### 获取ContainerReader容器尺寸

ContainerReader的主要接口包括ContainerReader和breakpointConfig。

*   ContainerReader接口
    
    [ContainerReader](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader)是实现容器断点的核心组件，其使用要求如下。[ContainerReaderInfo](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader#containerreaderinfo)所有参数都必须通过状态变量进行双向绑定。ContainerReader通过双向绑定机制，将后端计算的尺寸和断点值实时更新到状态变量中。不能通过改变此处[ContainerReaderInfo](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader#containerreaderinfo)的size来试图设置ContainerReader尺寸。在使用状态变量时需要添加[!!](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-binding)后缀，触发双向绑定更新。
    
*   breakpointConfig属性
    
    通过[breakpointConfig](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-containerreader#breakpointconfig)属性可以自定义断点阈值。断点数组必须为单调递增数组。其中，宽度断点最多支持5个，即数组最大长度为4；高度断点最多支持3个，即数组最大长度为2。断点区间为左闭右开区间\[breakpoint\[i\], breakpoint\[i+1\])。宽度断点值单位为vp；高度断点值为组件高度与宽度的比值，无单位。
    
    **异常处理规则：**
    
    | 异常情况 | 处理方式 |
    | :-- | :-- |
    | 数组大小超过最大数量。 | 使用系统默认断点。 |
    | 数组非递增。 | 取递增结束的子数组。 |
    | 数组中存在异常值（非数字等）。 | 跳过异常值，只处理有效值。 |
    
    **示例：**
    
    // 示例1：数组超过最大长度\[320, 600, 840, 1440, 2000, 3000\]
    // 超过部分被忽略，使用系统默认：\[320, 600, 840, 1440\]
    .breakpointConfig({ width: \[320, 600, 840, 1440, 2000, 3000\] })
    
    // 示例2：数组非递增\[100, 50, 300, 400\]
    // 取递增结束的子数组：\[100\]
    .breakpointConfig({ width: \[100, 50, 300, 400\] })
    
    // 示例3：数组包含异常值\[100, undefined, 300, 400\]
    // 跳过异常值undefined，处理有效值：\[100, 300, 400\]
    .breakpointConfig({ width: \[100, undefined, 300, 400\] })
    

下面介绍容器断点的简单开发步骤。

1.  声明状态变量。
    
    首先需要声明用于存储容器尺寸和断点信息的状态变量并初始化，防止在未获取ContainerReader的大小和断点时使用造成异常。
    
    @State containerSize: Size = { width: 0, height: 0 };
    @State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
    
2.  配置ContainerReader。
    
    将状态变量绑定到ContainerReader组件，使用!!后缀触发双向绑定更新。
    
    ContainerReader({
      size: this.containerSize!!,
      widthBreakpoint: this.widthBp!!
    }) {
      Column() {
        Text('Adaptive Content')
      }
      .width('100%')
      .height('100%')
    }
    
3.  确定容器尺寸。
    
    情况一：ContainerReader不显式设置尺寸，它通过以下方式自动获取尺寸。
    
    *   **撑满父容器**：当ContainerReader是父容器的唯一子组件时，自动撑满父容器。
    *   **撑满剩余空间**：当父容器Flex、Row或Column有非ContainerReader类型的子组件时，ContainerReader占满剩余空间。
    *   **按比例分配剩余空间**：当父容器Flex、Row或Column有多个ContainerReader子组件时，ContainerReader通过layoutWeight分配剩余空间。
    
    情况二：可以为ContainerReader设置布局约束等尺寸属性来约束其尺寸。当Flex、Row或Column容器中有多个ContainerReader子组件时，一般情况下按开发者书写顺序第一个ContainerReader会占满剩余空间，此时其余ContainerReader组件的主轴大小为0。当开发者给书写顺序靠前的ContainerReader设置了尺寸约束时，会按尺寸约束分配给ContainerReader空间，再将剩余空间分配给开发者写的下一个ContainerReader。
    
    以情况一的撑满父容器为例，Flex给子组件ContainerReader分配与Flex等大的空间。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/6c/v3/ZGPE0nU7Rla2RPYD8YtXvg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=83C35D6C19AAC95E7774210479225258C095E2651B5AE102C13D626190CF7C9F)
    
    使用ContainerReader需要同时导入ContainerReaderAttribute，否则会导致编译报错。
    
    import {ContainerReader, ContainerReaderAttribute, Size} from '@kit.ArkUI';
    @Entry
    @Component
    struct Example {
      @State containerSize: Size = { width: 0, height: 0 };
      @State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
      build() {
        Flex({ direction: FlexDirection.Row }) {
          ContainerReader({
            size: this.containerSize!!,
            widthBreakpoint: this.widthBp!!
          }) {
            Column() {
              Text('Adaptive Content')
            }
            .width('100%')
            .height('100%')
          }
          .backgroundColor('#F7F7F7')
        }
        .padding(10)
        .width('100%')
        .height(200)
        .backgroundColor('#D5D5D5')
      }
    }
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/8d/v3/zfpw6L94Ry6An55Dz5JgNw/zh-cn_image_0000002634008318.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=358BE4CBB987C774276479B365BB8D1CE90D1FA67BCF745D0DF1E2AF558297C1)
    

#### 实现独立断点

在同一组件中，可以同时使用多个ContainerReader组件，每个组件可以拥有独立的断点状态，实现更精细化的布局控制。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/28/v3/V29Q5KMOS2qjGTvvHdtTVQ/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=56469EADA4EFC2D2019F6DACB0355C7EDB08AFF07DE4F9C6DD90D2508E4AAB9E)

使用ContainerReader需要同时导入ContainerReaderAttribute，否则会导致编译报错。

import {ContainerReader, ContainerReaderAttribute, Size} from '@kit.ArkUI';
@Entry
@Component
struct MultiContainerExample {
  // 左右两个ContainerReader各自拥有独立的状态变量，互不影响
  @State leftContainerSize: Size = { width: 0, height: 0 };
  @State rightContainerSize: Size = { width: 0, height: 0 };
  @State leftWidthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
  @State rightWidthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;

  build() {
    Row({ space: 10 }) {
      // 左侧容器，独立感知自身尺寸和断点
      Flex({ direction: FlexDirection.Column }) {
        ContainerReader({
          size: this.leftContainerSize!!,
          widthBreakpoint: this.leftWidthBp!!
        }) {
          Column() {
            Text('Left Container')
          }
          .width('100%')
          .height('100%')
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#F0FAFF')
      }
      .layoutWeight(1)
      .height(300)

      // 右侧容器，独立感知自身尺寸和断点
      Flex({ direction: FlexDirection.Column }) {
        ContainerReader({
          size: this.rightContainerSize!!,
          widthBreakpoint: this.rightWidthBp!!
        }) {
          Column() {
            Text('Right Container')
          }
          .width('100%')
          .height('100%')
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#D5D5D5')
      }
      .layoutWeight(1)
      .height(300)
    }
    .width('100%')
    .padding(20)
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/da/v3/Vdw5LNOZQByfuKU5OU_Abg/zh-cn_image_0000002633848418.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=FE669F4A998B1D1411DD7599A261075115591D1291BB0196F2B3D4EB3A629D94)

#### 网格组件根据自身容器断点设置列数

在多设备开发中，网格组件（如[Grid](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-grid)）可以根据自身容器尺寸设置不同的列数，实现自适应的列表布局。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b4/v3/QKlMQQPqT9mcjDmiCM56uQ/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=453BC925DFE616F20C2BD86D52038B6488C2E70A235CF48DB9D4539944489A3A)

使用ContainerReader需要同时导入ContainerReaderAttribute，否则会导致编译报错。

import {ContainerReader, ContainerReaderAttribute, Size} from '@kit.ArkUI';
@Entry
@Component
struct GridBreakpointExample {
  @State containerSize: Size = { width: 0, height: 0 };
  @State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
  @State bgColors: ResourceColor\[\] =
    \['#707070', '#004AAF', '#2787D9', '#F7F7F7', '#F0FAFF'\];

  build() {
    Column({ space: 10 }) {
      Text('Grid with Container Breakpoint')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      // ContainerReader包裹Grid，根据容器宽度断点动态调整列数
      Flex({ direction: FlexDirection.Column }) {
        ContainerReader({
          size: this.containerSize!!,
          widthBreakpoint: this.widthBp!!
        }) {
          Grid() {
            ForEach(this.bgColors, (color: ResourceColor, index?: number) => {
              GridItem() {
                Row() {
                  Text(\`${index}\`)
                }
                .width('100%')
                .height('50vp')
                .justifyContent(FlexAlign.Center)
              }
              .backgroundColor(color)
            })
          }
          // 根据断点值动态设置列模板
          .columnsTemplate(this.getColumnsTemplate())
          .columnsGap(10)
          .rowsGap(10)
          .width('100%')
          .height('100%')
        }
        .width('100%')
        .height(300)
        .backgroundColor('#FFFFFF')
      }
      .width('80%')
      .height(320)
      .padding(10)
      .backgroundColor('#D5D5D5')
      .border({ width: 1, color: '#D5D5D5' })
    }
    .width('100%')
    .padding(20)
  }

  // 根据宽度断点返回对应的列模板
  getColumnsTemplate(): string {
    if (this.widthBp === WidthBreakpoint.WIDTH\_XS) {
      return '1fr';
    } else if (this.widthBp === WidthBreakpoint.WIDTH\_SM) {
      return '1fr 1fr';
    } else if (this.widthBp === WidthBreakpoint.WIDTH\_MD) {
      return '1fr 1fr 1fr';
    } else {
      return '1fr 1fr 1fr 1fr';
    }
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/c7/v3/vfxt-BemQoi_Pre_HK_axA/zh-cn_image_0000002634008320.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=EE2E46953742CA9485D7ED3FD2716B75F617F6732E555537707947EAFF39DB0F)

#### 自定义组件根据容器断点自适应布局

开发者可以创建自定义组件，组件内部使用ContainerReader来实现自适应的内部布局，使组件在不同的使用场景下都能呈现最佳效果。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e2/v3/k7hY799CRBWWrzEFOZmwfQ/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=D8C501B13C8F3E7B90ECC7D7D4C3E32AE6DEB27394D89014A61593AE7CACE8C7)

使用ContainerReader需要同时导入ContainerReaderAttribute，否则会导致编译报错。

import {ContainerReader, ContainerReaderAttribute, Size} from '@kit.ArkUI';

// 自适应卡片组件，内部使用ContainerReader感知容器尺寸
@Component
struct AdaptiveCard {
  @State containerSize: Size = { width: 0, height: 0 };
  @State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
  @Prop title: string = 'Card Title';
  @Prop content: string = 'Card content text';

  build() {
    ContainerReader({
      size: this.containerSize!!,
      widthBreakpoint: this.widthBp!!
    }) {
      Text('width' + this.containerSize?.width)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#D5D5D5')
    .border({ width: 1, color: '#D5D5D5', radius: 8 })
  }
}

// 使用不同尺寸的容器展示AdaptiveCard的自适应效果
@Entry
@Component
struct AdaptiveCardExample {
  build() {
    Column({ space: 20 }) {
      Text('Adaptive Card Components')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Text('Small Container:')
        .fontSize(14)
        .fontColor('#707070')
        .alignSelf(ItemAlign.Start)

      AdaptiveCard({
        title: 'Small Card',
        content: 'This card adapts to small containers with vertical layout.'
      })
        .width(200)
        .height(200)

      Text('Large Container:')
        .fontSize(14)
        .fontColor('#707070')
        .alignSelf(ItemAlign.Start)

      AdaptiveCard({
        title: 'Large Card',
        content: 'This card adapts to large containers with horizontal layout.'
      })
        .width(300)
        .height(150)
    }
    .width('100%')
    .padding(20)
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/4a/v3/nM6O8DF9R1K3cnlGj9buSw/zh-cn_image_0000002664207469.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=14988C95320EB3E10C3FF047BAF01A89D099789F2A62B2BDBBAC53222AB7C5B3)

#### 左右分栏布局自适应

在主从结构页面中，左侧为固定宽度的Tab标签，右侧为自适应的详情区域。右侧详情区域使用ContainerReader，根据剩余宽度自动切换布局：窄屏时上下排列，宽屏时左右排列。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ee/v3/qnLMaQnkSFGZEU4hR_b9Bw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=2D80CE3B1D51B8316E1D31540329BA15275A98A0376FA4D28F68B81D43920CC7)

使用ContainerReader需要同时导入ContainerReaderAttribute，否则会导致编译报错。

import { ContainerReader, ContainerReaderAttribute, Size } from '@kit.ArkUI';

@Entry
@Component
struct SplitLayoutExample {
  @State containerSize: Size = { width: 0, height: 0 };
  @State widthBp: WidthBreakpoint = WidthBreakpoint.WIDTH\_MD;
  @State currentTabIndex: number = 0;
  private menuItems: string\[\] = \['选项一', '选项二', '选项三', '选项四'\];

  build() {
    Column() {
      Text('分栏布局')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 10 })

      Flex({ direction: FlexDirection.Row }) {
        // 左侧：垂直方向的Tabs标签栏，固定宽度100
        Tabs({ barPosition: BarPosition.Start, index: this.currentTabIndex }) {
          ForEach(this.menuItems, (item: string, index?: number) => {
            TabContent() {
              // 右侧：ContainerReader感知TabContent区域宽度
              ContainerReader({
                size: this.containerSize!!,
                widthBreakpoint: this.widthBp!!
              }) {
                this.buildDetailContent()
              }
              .padding(10)
            }
            .tabBar(item)
          }, (item: string, index?: number) => \`${index}\`)
        }
        .onChange((index: number) => {
          this.currentTabIndex = index;
        })
        .vertical(true)
        .barWidth(100)
        .backgroundColor('#F7F7F7')
      }
      .width('100%')
      .height(300)
    }
    .width('100%')
    .padding(20)
  }

  // 根据断点切换详情区域布局
  @Builder
  buildDetailContent() {
    if (this.widthBp === WidthBreakpoint.WIDTH\_XS || this.widthBp === WidthBreakpoint.WIDTH\_SM) {
      // 窄屏：标题和内容上下排列
      Column({ space: 10 }) {
        Column() {
          Text('标题区域')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
        }
        .width('100%')
        .height(60)
        .backgroundColor('#FFFFFF')
        .borderRadius(8)
        .justifyContent(FlexAlign.Center)

        Column() {
          Text('内容区域')
            .fontSize(14)
        }
        .width('100%')
        .layoutWeight(1)
        .backgroundColor('#F0FAFF')
        .borderRadius(8)
        .justifyContent(FlexAlign.Center)
      }
      .width('100%')
      .height('100%')
    } else {
      // 宽屏：标题和内容左右排列
      Row({ space: 10 }) {
        Column() {
          Text('标题区域')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
        }
        .width(120)
        .height('100%')
        .backgroundColor('#FFFFFF')
        .borderRadius(8)
        .justifyContent(FlexAlign.Center)

        Column() {
          Text('内容区域')
            .fontSize(14)
        }
        .layoutWeight(1)
        .height('100%')
        .backgroundColor('#F0FAFF')
        .borderRadius(8)
        .justifyContent(FlexAlign.Center)
      }
      .width('100%')
      .height('100%')
    }
  }
}

窄屏时上下排列。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ed/v3/rO8RpkPRTA6TjxuCYiO6lg/zh-cn_image_0000002664327529.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=FBA362C434040693CFC7CD8F62855A389C59E9B67414DE09122297F9041EE18B)

宽屏时左右排列。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d/v3/SUjSJlnSSUGMdDWb54SjEw/zh-cn_image_0000002633848420.png?HW-CC-KV=V1&HW-CC-Date=20260709T132258Z&HW-CC-Expire=86400&HW-CC-Sign=706711831396339340BBDD41CEC888416A3CD37126A807D3CF1DEF53EB258A78)