DEV Community

HarmonyOS
HarmonyOS

Posted on

Calculate text pagination data

Read the original article:Calculate text pagination data

Problem Description

A long text with adjustable font size. Calculate how many pages the current text is divided into and the number of lines on each page based on the text and font size.

Background Knowledge

Solution

1. Get the width and height of the currently used device.

   this.displayClass = display.getDefaultDisplaySync();
Enter fullscreen mode Exit fullscreen mode

2. Get the height of the navigation bar and status bar, and set it in the onWindowStageCreate() method of EntryAbility.ets.

   // Obtain the main window of the application.
   let windowClass: window.Window = windowStage.getMainWindowSync();
   // Obtain the area for layout to avoid obstruction.
   let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // Navigation bar avoidance
   let avoidArea = windowClass.getWindowAvoidArea(type);
   let bottomRectHeight = avoidArea.bottomRect.height; // Get the height of the navigation bar area
   AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
   type = window.AvoidAreaType.TYPE_SYSTEM; // Status bar avoidance
   avoidArea = windowClass.getWindowAvoidArea(type);
   let topRectHeight = avoidArea.topRect.height; // Get the height of the status bar area
   AppStorage.setOrCreate('topRectHeight', topRectHeight);
Enter fullscreen mode Exit fullscreen mode

3. Number of lines that can be displayed per page: After obtaining the actual height of the page, the number of lines that can be displayed per page is calculated as the total height divided by the height of each line (obtained using MeasureText.measureTextSize).

   // Number of lines that can be displayed per page
   heightCalculator() {
     if (this.displayClass) {
       // Subtract the height of the top status bar and bottom navigation bar from the device height to obtain the actual height of the page.
       let trueHeight = this.displayClass.height - this.topRectHeight - this.bottomRectHeight
       console.info(`Screen height:${trueHeight}`)
       // Number of lines that can be displayed per page
       this.pageLines = Math.ceil(trueHeight / this.lineHeight)
     }
   }
Enter fullscreen mode Exit fullscreen mode

4. Number of pages: Obtain the total number of lines in the component content using the getLineCount method. Then, divide the total number of lines by the number of lines displayed per page to get the total number of pages.

   // Calculate the number of pages
     pageNum() {
       let layoutManager: LayoutManager = this.controller.getLayoutManager()
       let lineCount = layoutManager.getLineCount()
       this.lineCount = lineCount
       console.info(`Total number of rows:${this.lineCount}`)
       // Final number of pages
       let pagesNum: number = Math.ceil(this.lineCount / this.pageLines)
       console.info(`Number of lines per page:${this.pageLines}`)
       console.info(`Total number of pages:${pagesNum} `)
     }
Enter fullscreen mode Exit fullscreen mode

Overall, it is as follows:

// Index.ets
import { display } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State lineSize: SizeOptions = { height: 0, width: 0 } // Total length of the text
  @State displayClass: display.Display | null = null;
  @State str: string =
    'During application development and layout, text elements and content need to be typed, measured, drawn, and displayed. The font engine development framework provides a series of interface capabilities to support application layout text and manage fonts. During application development and layout, text elements and content need to be typed, measured, drawn, and displayed. The font engine development framework provides a series of interface capabilities to support application layout text and manage fonts. During application development and layout, text elements and content need to be typed, measured, drawn, and displayed. The font engine development framework provides a series of interface capabilities to support application layout text and manage fonts. During application development and layout, text elements and content need to be typed, measured, drawn, and displayed. The font engine development framework provides a series of interface capabilities to support application layout text and manage fonts. During application development and layout, text elements and content need to be typed, measured, drawn, and displayed. The font engine development framework provides a series of interface capabilities to support application layout text and manage fonts. During application development and layout, text elements and content need to be typed, measured, drawn, and displayed. The font engine development framework provides a series of interface capabilities to support application layout text and manage fonts.'
  @State lineHeight: number = 0
  @StorageProp('topRectHeight') topRectHeight: number = 0;
  @StorageProp('bottomRectHeight') bottomRectHeight: number = 0;
  @State lineCount: number = 0;
  private controller: TextController = new TextController()
  @State pageLines: number = 0 // Number of rows displayed per page

  aboutToAppear(): void {
    this.lineSize = this.getUIContext().getMeasureUtils().measureTextSize({ textContent: this.str, fontSize: '16px' })
    this.displayClass = display.getDefaultDisplaySync(); // Get the page height and width of the device
    this.lineHeight = this.lineSize.height as number
    console.info(`Text height:${this.lineHeight}`)
    this.heightCalculator()
  }

  // Number of lines that can be displayed per page
  heightCalculator() {
    if (this.displayClass) {
      // Subtract the height of the top status bar and bottom navigation bar from the device height to obtain the actual height of the page.
      let trueHeight = this.displayClass.height - this.topRectHeight - this.bottomRectHeight
      console.info(`Screen height:${trueHeight}`)
      // Number of lines that can be displayed per page
      this.pageLines = Math.ceil(trueHeight / this.lineHeight)
    }
  }

  // Calculate the number of pages
  pageNum() {
    let layoutManager: LayoutManager = this.controller.getLayoutManager()
    let lineCount = layoutManager.getLineCount()
    this.lineCount = lineCount
    console.info(`Total number of rows:${this.lineCount}`)
    // Final number of pages
    let pagesNum: number = Math.ceil(this.lineCount / this.pageLines)
    console.info(`Number of lines per page:${this.pageLines}`)
    console.info(`Total number of pages:${pagesNum} `)
  }

  build() {
    Column() {
      Scroll() {
        Text(this.str, { controller: this.controller })
          .fontSize('16px')
          .width('100%')
          .onAreaChange((oldArea, newArea) => {
            // Triggered when the text area changes (after rendering is complete)
            this.pageNum()
          })
      }
    }
    .height('100%')
    .width('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

The printed log is as follows:

kbs--677ea5f2633546b0b83dc20a0e004431-44d4.png
Note: The font size in the build should be consistent with the font size used in MeasureText.measureTextSize.

Verification Result

The execution result is as follows:

kbs--9c633b0fdcd6476ba0688220c0f973d6-35a4b.png

Written by Emrecan Karakas

Top comments (0)