计算文本分页数据
========

#### 问题现象

一段长文本，字体大小可修改，根据文本和字体大小计算当前文本分为几页，以及每页上的行数。

#### 背景知识

*   [measureTextSize](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-measureutils#measuretextsize12)：计算指定文本的宽度和高度。
*   [getDefaultDisplaySync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-display#displaygetdefaultdisplaysync9)：获取当前默认的display对象。
*   [getLineCount](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-graphics-text#getlinecount)用于返回文本的总行数。

#### 解决方案

1.  获取导航条和状态栏的高度，在EntryAbility.ets的onWindowStageCreate()中设置。
    
    let windowClass \= windowStage.getMainWindowSync();
    _//_ _获取布局避让遮挡的区域_
    let type \= window.AvoidAreaType.TYPE\_NAVIGATION\_INDICATOR; _// 导航条避让_
    let avoidArea \= windowClass.getWindowAvoidArea(type);
    let bottomRectHeight \= avoidArea.bottomRect.height; _//_ _获取到导航条区域的高度_
    AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
    
    type \= window.AvoidAreaType.TYPE\_SYSTEM; _//_ _状态栏避让_
    avoidArea \= windowClass.getWindowAvoidArea(type);
    let topRectHeight \= avoidArea.topRect.height; _// 获取状态栏区域高度_
    AppStorage.setOrCreate('topRectHeight', topRectHeight);
    
2.  每页能展示的行数：获取页面的真实高度后，每页能展示的行数即为总高度/每行的高度（通过MeasureText.measureTextSize获取）。
    
    _//_ _每页能展示的行数_
    heightCalculator() {
      if (this.displayClass) {
       _ // 将设备高度减去顶部状态栏和底部导航条得到页面的真实高度_
        let trueHeight \= this.displayClass.height \- this.topRectHeight \- this.bottomRectHeight;
        console.info(\`屏幕高度:${trueHeight}\`);
       _ // 每页能展示的行数_
        this.pageLines \= Math.ceil(trueHeight / this.lineHeight);
      }
    }
    
3.  页面的数量：通过getLineCount方法获取组件内容的总行数，再用总行数/每页展示的行数即为总页数。
    
    _//_ _计算页面数量_
    pageNum() {
      let layoutManager: LayoutManager \= this.controller.getLayoutManager();
      let lineCount \= layoutManager.getLineCount();
      this.lineCount \= lineCount;
      console.info(\`总行数:${this.lineCount}\`);
     _ // 最终的页面数量_
      let pagesNum: number \= Math.ceil(this.lineCount / this.pageLines);
      console.info(\`每页行数:${this.pageLines}\`);
      console.info(\`总页数:${pagesNum} \`);
    }
    

完整示例参考如下：

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

@Entry
@Component
struct Index {
  private lineSize: SizeOptions \= { height: 0, width: 0 }; _// 文本的总长度_
  private displayClass: display.Display | null \= null;
  private str: string \=
    '应用在开发和布局时，经常需要针对文本元素和内容进行排版、测量、绘制和显示等。字体引擎开发框架提供了一系列接口能力用于支持应用布局文本和管理字体。应用在开发和布局时，经常需要针对文本元素和内容进行排版、测量、绘制和显示等。字体引擎开发框架提供了一系列接口能力用于支持应用布局文本和管理字体。应用在开发和布局时，经常需要针对文本元素和内容进行排版、测量、绘制和显示等。字体引擎开发框架提供了一系列接口能力用于支持应用布局文本和管理字体。应用在开发和布局时，经常需要针对文本元素和内容进行排版、测量、绘制和显示等。字体引擎开发框架提供了一系列接口能力用于支持应用布局文本和管理字体。应用在开发和布局时，经常需要针对文本元素和内容进行排版、测量、绘制和显示等。字体引擎开发框架提供了一系列接口能力用于支持应用布局文本和管理字体。应用在开发和布局时，经常需要针对文本元素和内容进行排版、测量、绘制和显示等。字体引擎开发框架提供了一系列接口能力用于支持应用布局文本和管理字体';
  private 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; _// 每页展示的行数_

  aboutToAppear(): void {
    this.lineSize \= this.getUIContext().getMeasureUtils().measureTextSize({ textContent: this.str, fontSize: '100px' });
    this.displayClass \= display.getDefaultDisplaySync(); _// 获取设备的页面高度和宽度_
    this.lineHeight \= this.lineSize.height as number;
    console.info(\`文本高度:${this.lineHeight}\`);
    this.heightCalculator();
  }

 _ // 每页能展示的行数_
  heightCalculator() {
    if (this.displayClass) {
    _  // 将设备高度减去顶部状态栏和底部导航条得到页面的真实高度_
      let trueHeight \= this.displayClass.height \- this.topRectHeight \- this.bottomRectHeight;
      console.info(\`屏幕高度:${trueHeight}\`);
     _ // 每页能展示的行数_
      this.pageLines \= Math.ceil(trueHeight / this.lineHeight);
    }
  }

  _// 计算页面数量_
  pageNum() {
    let layoutManager: LayoutManager \= this.controller.getLayoutManager();
    let lineCount \= layoutManager.getLineCount();
    this.lineCount \= lineCount;
    console.info(\`总行数:${this.lineCount}\`);
    _// 最终的页面数量_
    let pagesNum: number \= Math.ceil(this.lineCount / this.pageLines);
    console.info(\`每页行数:${this.pageLines}\`);
    console.info(\`总页数:${pagesNum} \`);
  }

  build() {
    Column() {
      Scroll() {
        Text(this.str, { controller: this.controller })
          .fontSize('100px')
          .width('100%')
          .onAreaChange(() \=\> {
        _    // 当文本区域变化时（渲染完成）触发_
            this.pageNum();
          })
      }
    }
    .height('100%')
    .width('100%')
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ce/v3/qNcuOUZUROeMugv1qLgDcw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T134044Z&HW-CC-Expire=86400&HW-CC-Sign=307B9F5BB7F06C908DFBCAEB9A54CEB71C7F07107C0D158405B89170DBEF4227)

build中的字体大小和MeasureText.measureTextSize的字体大小需保持一致。