容器断点 (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/ad/v3/VFj9-qqFSSqVW7xot6K1Fw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=BA090C5C915B470C6FF6185EB9137794638160393BB09E030C0000747FA9B1BB)

*   当父容器为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/6b/v3/SWZBLFVhST6Xgp41h2GJzw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=778107870AB8D8F088F72BDB40244E16E9C59F8789CDCC35AEAE9FDBFDCF88A3)

使用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/a0/v3/6i_vqSHaQJiKLzb9GorIUQ/zh-cn_image_0000002625107411.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=FABDD4033C5CFCF56868391A2FC417E1DF273EA79DD03A65630BFCCF5E77287A)

[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/17/v3/eB7orAJBQrizJBz00gYaKg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=B1EF13092B0947B2C72FEE3D95A2A16227EB54D9617ABD88B607F0BBA6AF02F7)

使用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/24/v3/GoaUQGltQo-yvVqVxQDFGg/zh-cn_image_0000002594667894.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=DEC30F3080EE1600F340B9F673F89BA98D04F3F5FD44D6AEBC5C990D6BF9EB0C)

当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/0/v3/JXgPM7PaQ4-tYlNq7m4ShA/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=AA6123C59C44C5036F21C31944E8D2CC671DB170ED962EDBB1CC60B2190AF320)

使用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/e2/v3/sM1R5jLeTACciFlKMVrYgg/zh-cn_image_0000002594827822.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=1B9E01F0FF62E7A1BCE5977A1954838DB6FDB464D93C59CF9154E4CA4E23EB70)

#### 约束与限制

**状态变量要求**

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!!
    }) {
      // 子组件内容
    }
    
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/af/v3/N5iki3a-Qk23Uou_Yw5s2g/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=D6FC2142CC53A45868902A9E2E79236930C5AC2E8358806CA62ACC463E3ACE4E)
    
    使用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/35/v3/T0MJYLbtRwuyTVp1x-ncpQ/zh-cn_image_0000002625107411.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=563E92E7ECD77CBC72184005E2B15A62CE34D7151EA33C6BD48F1C2054E46C8B)
    

#### 实现独立断点

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

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/67/v3/0GspiNqhQKSCvsz5Cq_Jkg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=BFA215D43EE026181773B38C6E18240E8F9313E9B7FE5861400E1D048264A488)

使用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/ff/v3/A_pPiTPCRkiAw6Ho9RCKfQ/zh-cn_image_0000002625187269.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=283DFEFDF4BD944457753860701D097ECC050178A3BD855974344C3F5350F881)

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

在多设备开发中，网格组件（如[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/af/v3/TECK8092S8-AwYRLoKysMg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=F3F4CD67F5479865910A7A8466CC6F8909F776003DC14FF02C859717390308E7)

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

// xxx.ets
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/61/v3/GSBmPGjeS666mlFu-E7WBQ/zh-cn_image_0000002625107413.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=0647603A2BCBFA1296464134823900D960946004C8C0264F2D1E6A4A2EB2FF26)

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

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

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/a2/v3/W-XxL74YQlCVW0TQ9PAKJA/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=3ACF6D592DB0E8F2DB466F9543FC3455A4E8B4BBEA9B2653C414EE77DBCA888F)

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

// xxx.ets
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/fe/v3/sAyjl6t2RwiYANn-7mXe4g/zh-cn_image_0000002594667896.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=5D43646C2F14A8EDB628BC39601F2EF4C4D4A9061B30C684BCB6CDB3598E98D6)

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

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

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/92/v3/mFqfDDzuT5ipmndJ1e2_HA/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=D5DD31BE102BBD77F0523CBBDD403F69532A927544A1307EBE44C6A485062184)

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

// xxx.ets
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/c4/v3/7AtvaZOyRzueoNU4ntpBPw/zh-cn_image_0000002594827824.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=538B5C3ABEFD2B5E3FB6AB99582492EF1C75E7E55F2D9DAF6C8495346E4F2349)

宽屏时左右排列。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/19/v3/qxYEmTteQFS9wSao5NfBMA/zh-cn_image_0000002625187271.png?HW-CC-KV=V1&HW-CC-Date=20260612T073302Z&HW-CC-Expire=86400&HW-CC-Sign=D7E070A22632BB932154D12ED149F4E53F7E85713F20CEF84453AF449C1E9250)