DEV Community

HarmonyOS
HarmonyOS

Posted on

How to Achieve Width and Height Adaptation of Text Component within a Set Range

Read the original article:How to Achieve Width and Height Adaptation of Text Component within a Set Range

Context

This article addresses the issue where Text components in Row layouts exceed their parent container’s boundaries when containing long text, and provides solutions for adaptive sizing within constraints.

Description

In a Row layout, when the left side contains a fixed-size component and the right side contains a Text component’s parent that should occupy the remaining space, excessive text in the Text component may exceed the parent’s designated area.

How to achieve width and height adaptation of the Text component within its parent’s set boundaries to prevent overflow?

  • The Row component is a horizontal layout container. When nested, outer Row properties may not affect inner child components as expected. For example, setting the constraintSize property on the outer Row can cause the inner Text component to exceed its set range.
  • The Text component can use the constraintSize property to set dimensional constraints, ensuring it varies freely within defined limits with higher priority than width and height.

Solution

Calculate the maximum width and height of the Text’s parent within the Row container, then use the constraintSize property to constrain the Text component’s maximum dimensions, achieving adaptive sizing within the set range. Implementation steps:

1.Apply constraintSize directly to the Text component to constrain its dimensions. Calculate the maximum size values where Text’s maximum width equals: parent maxWidth - left fixed component width (stableWidth) - parent’s left padding (margin.left) - parent’s right padding (margin.right). Perform calculations in the aboutToAppear lifecycle method:

  aboutToAppear(): void {
    try {
      let screenW = this.getUIContext().px2vp(display.getDefaultDisplaySync().width)
      // Get the screen width and convert it to vp.
      let stableW =
        this.getUIContext()
          .px2vp(this.uiContext?.getHostContext()?.resourceManager.getNumber($r('app.float.page_text_font_size').id));
      // Get the font size of the page and convert it to vp.
      let marginR = Number(this.removeCharater(this.marginRight as string))
      // Remove the numeric characters from the right margin and convert them to numbers.
      let marginL = this.marginLeft as number
      // Left margin directly converted to number
      let marginT = this.getUIContext()
        .px2vp(this.uiContext?.getHostContext()?.resourceManager.getNumber((this.marginTop as Resource).id))
      // Top margin directly converted to vp
      this.maxWidth = screenW - stableW - marginR - marginL - marginT // Calculate the maximum width
      console.info(`this.maxWidth: ${this.maxWidth}`) // Maximum Print Width
    } catch (error) {
    }
  }

Enter fullscreen mode Exit fullscreen mode

2.Obtain the Text’s maximum dimensions in the Row and pass them to the constraintSize property to dynamically set the Text component’s size, preventing text overflow:

 Row() {
          Text(this.str)
            .constraintSize({ maxWidth: this.maxWidth })
            .fontColor(Color.Black)
        }
        .margin({ left: 10, right: 10 })
Enter fullscreen mode Exit fullscreen mode

Complete code example:

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')

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

  aboutToAppear(): void {
    try {
      let screenW = this.getUIContext().px2vp(display.getDefaultDisplaySync().width)
      // Get the screen width and convert it to vp.
      let stableW =
        this.getUIContext()
          .px2vp(this.uiContext?.getHostContext()?.resourceManager.getNumber($r('app.float.page_text_font_size').id));
      // Get the font size of the page and convert it to vp.
      let marginR = Number(this.removeCharater(this.marginRight as string))
      // Remove the numeric characters from the right margin and convert them to numbers.
      let marginL = this.marginLeft as number
      // Left margin directly converted to number
      let marginT = this.getUIContext()
        .px2vp(this.uiContext?.getHostContext()?.resourceManager.getNumber((this.marginTop as Resource).id))
      // Top margin directly converted to vp
      this.maxWidth = screenW - stableW - marginR - marginL - marginT // Calculate the maximum width
      console.info(`this.maxWidth: ${this.maxWidth}`) // Maximum Print Width
    } 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 })
            .fontColor(Color.Black)
        }
        .margin({ left: 10, right: 10 })
      }
      .backgroundColor('#fff2f5f5')
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#ffeeeaea')
    .justifyContent(FlexAlign.Center)
  }
}
Enter fullscreen mode Exit fullscreen mode

Q: In the aboutToAppear method of the solution, when using getNumber to retrieve data, are the units always in px?

A: Data retrieved via getNumber is always in px. For example, Integer values are raw numbers, while float values without units are raw numbers, and those with “vp” or “fp” units correspond to px values. Refer to the official Resource Management documentation.

Constraints and Limitations

  • Supported API Version: 19 Release and above
  • Supported SDK: HarmonyOS 5.1.1 Release and above
  • Requires DevEco Studio 5.1.1 Release or newer for compilation

Key Takeaways

  • Use constraintSize on Text components to prevent overflow in Row layouts
  • Calculate dynamic max dimensions based on parent/container measurements
  • Perform sizing calculations in aboutToAppear lifecycle for accurate results
  • Consider unit conversions (px/vp/fp) when retrieving layout data

Reference Link

Written by Fatih Muti

Top comments (0)