1. 程式人生 > >閱讀器的分頁實現

閱讀器的分頁實現

最近在寫一個閱讀器app,命名為Light,程式碼已經開源,點選檢視Light原始碼
本專案基於Flutter,瞭解更多請點選flutter.io
本方案的核心原理是利用了TextPainter特性,通過多次渲染來找到當前頁面能夠顯示的最大字元數。

文字描述:獲得一段內容後呼叫TextPainter.layout(),如果發生行溢位則減少字元數量,如果未溢位則增加字元數量,不斷迴圈這個過程,直到這些字元恰好能夠填滿整個頁面且不溢位,那麼就完成了一次分頁計算。以防萬一,對迴圈設定一個次數上限。

程式流程圖如下:
這裡寫圖片描述


  /// 獲取帶樣式的文字物件
  TextSpan getTextSpan(String text
) { return new TextSpan(text: text, style: _textStyle); } /// 接收內容 /// 追加內容返回false /// 計算完畢返回true bool load(String text) { if (layout(text)) { return false; } int start = 0; int end = text.length; int mid = (end + start) ~/ 2; // 最多迴圈20次 for (int i = 0; i < 20; i++) { if
(layout(text.substring(0, mid))) { if (mid <= start || mid >= end) break; // 未越界 start = mid; mid = (start + end) ~/ 2; } else { // 越界 end = mid; mid = (start + end) ~/ 2; } } length = mid; return true; } /// 計算待繪製文字 /// 未超出邊界返回true
/// 超出邊界返回false bool layout(String text) { times++; text = text ?? ''; textPainter ..text = getTextSpan(text) ..layout(maxWidth: pageSize.width); return !didExceed; } /// 是否超出邊界 bool get didExceed { return textPainter.didExceedMaxLines || textPainter.size.height > pageSize.height; }

完成一次計算的平均時間為23毫秒,在閱讀時幾乎感覺不到卡頓,但是對於整書的分頁計算來說還是很耗時。
這裡寫圖片描述

如果有問題歡迎即時交流,期待您更精彩的方案。