Text组件如何在设定范围内实现宽高自适应
=====================

#### 问题现象

在Row布局中，左边是固定宽高组件，右边是Text组件的父组件，并且要求父组件占据Row组件剩余空间，但是当Text组件文字过多时会超出父组件设定范围，如何实现Text组件在父组件设定范围内的宽高自适应，避免超出父组件的设定范围？

问题效果预览：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b1/v3/Wz9_ZYQJRSetmP8ERJK4rA/zh-cn_image_0000002658848481.gif?HW-CC-KV=V1&HW-CC-Date=20260709T133955Z&HW-CC-Expire=86400&HW-CC-Sign=72BF34FF604E1B32243F5A24D0EBF5EE8D30AFCCA61B3FFD3EA3D4599AAA2E7F "点击放大")

#### 效果预览

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/23/v3/VjDHKRI2TL-9PqGdHyGaCQ/zh-cn_image_0000002628609220.gif?HW-CC-KV=V1&HW-CC-Date=20260709T133955Z&HW-CC-Expire=86400&HW-CC-Sign=68FC6FB2BC0D09F13F709D81E1409CFD23FBDA41CA8CBBC7A2F55BD95C223A2B "点击放大")

#### 背景知识

*   [Row](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-row)组件是沿水平方向布局容器，Row组件在嵌套使用时，设置在外层的属性可能不会对内层子组件起到预期的效果，比如将constraintSize属性设置在外层Row时会导致内层Row中的子组件Text超出设定的范围。
*   [Text](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-text)组件能够使用[constraintSize](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-securitycomponent-attributes#constraintsize11)属性来设置约束尺寸，保证Text组件在设定好的范围内自由变动，并且其优先级高于[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)。

#### 解决方案

可以通过计算得出Text父组件在Row容器下的最大宽高，以此来设置属性constraintSize约束Text组件的最大尺寸，实现Text组件在设定范围内的宽高自适应。具体实现如下：

1.  将constraintSize属性设置在Text组件下，约束Text组件的尺寸，并且通过计算，得出最大尺寸的具体值，Text的constraintSize属性的最大宽度是由：父组件的宽度maxWidth减去左边固定宽高组件的宽度stableWidth，再减去父组件左内边距margin.left，再减去父组件右内边距margin.right之后即可得到。在aboutToAppear生命周期方法中进行计算：
    
    aboutToAppear(): void {
      try {
        let screenW \= this.getUIContext().px2vp(display.getDefaultDisplaySync().width);
       _ // 获取屏幕宽度，并转换为vp_
        let stableW \=
        this.getUIContext()
          .px2vp(this.uiContext?.getHostContext()?.resourceManager.getNumber($r('app.float.page\_text\_font\_size').id));
     _   // 获取页面字体大小，并转换为vp_
        let marginR \= Number(this.removeCharacter(this.marginRight as string));
        let marginL \= this.marginLeft as number;
     _   // 左边距直接转换为数字_
        let marginT \= this.getUIContext()
          .px2vp(this.uiContext?.getHostContext()?.resourceManager.getNumber((this.marginTop as Resource).id));
       _ // 顶部边距直接转换为vp_
        this.maxWidth \= screenW \- stableW \- marginR \- marginL \- marginT; _// 计算最大宽度_
        console.info(\`this.maxWidth: ${this.maxWidth}\`); _// 打印最大宽度_
      } catch (error) {
      }
    }
    
2.  得出Text的在Row组件中的最大尺寸，并将其传入constraintSize属性，即可动态指定Text组件的尺寸，防止文字超出文本框。
    
    Row() {
      Text(this.str).constraintSize({ maxWidth: this.maxWidth })
        .onClick(() \=\> {
          this.str \= this.str \+ '';
        });
    }
    

完整示例参考如下：

import { display } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State str: string \= '123';
  uiContext \= this.getUIContext();
  @State maxWidth: number \= 0;
  marginRight: Length \= '16vp';
  marginLeft: Length \= 16;
  marginTop: Length \= $r('app.float.page\_text\_font\_size');

  removeCharacter(str: string) {
    let result \= str.replace(/\[a-zA-Z\]/g, '');
    return result;
  }

  aboutToAppear(): void {
    try {
      let screenW \= this.getUIContext().px2vp(display.getDefaultDisplaySync().width);
   _   // 获取屏幕宽度，并转换为vp_
      let stableW \=
        this.getUIContext()
          .px2vp(this.uiContext?.getHostContext()?.resourceManager.getNumber($r('app.float.page\_text\_font\_size').id));
    _  // 获取页面字体大小，并转换为vp_
      let marginR \= Number(this.removeCharacter(this.marginRight as string));
      let marginL \= this.marginLeft as number;
   _   // 左边距直接转换为数字_
      let marginT \= this.getUIContext()
        .px2vp(this.uiContext?.getHostContext()?.resourceManager.getNumber((this.marginTop as Resource).id));
  _    // 顶部边距直接转换为vp_
      this.maxWidth \= screenW \- stableW \- marginR \- marginL \- marginT; _//_ _计算最大宽度_
      console.info(\`this.maxWidth: ${this.maxWidth}\`); _//_ _打印最大宽度_
    } catch (error) {
    }
  }

  build() {
    Column() {
      TextInput({ text: $$this.str });
      Row() {
        Row() {
          Row().width(50).height(50).backgroundColor('#ff18a2d0');
        };

        Row() {
          Text(this.str).constraintSize({ maxWidth: this.maxWidth })
            .onClick(() \=\> {
              this.str \= this.str \+ '';
            });
        }
        .margin({ left: 10, right: 10 });
      }
      .backgroundColor('#fff2f5f5');
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#ffeeeaea')
    .justifyContent(FlexAlign.Center);
  }
}

#### 常见FAQ

Q：在解决方案的aboutToAppear方法中，使用getNumber方法获取其中的数据，得到的数据单位都是px吗？

A：用getNumber方法获取数据的数据单位都是px。例如Integer对应的是原数值，float中的数不带单位时对应的是原数值，带"vp"，"fp"单位时对应的是px值。具体参考官网[资源管理](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-resource-manager)。