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) {
}
}
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 })
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)
}
}
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
Top comments (0)