詳解Flutter如何獲取Text截斷后的字符串
問題
當Text
文本設置maxLins
屬性將文本強制截斷之后,Text
的承載字符串是截斷前?還是截斷后的呢?我們該如何獲取截斷后的字符串呢?
答案是:截斷前,截斷字符串的操作并不會改變Text
的真實文本內(nèi)容屬性,無論原生還是Flutter
截斷字符串的操作只是對TextUI
組件的繪制區(qū)域施加一個限制。
那么我們需要從源碼里看下當我們設置了maxLine
這個屬性以后,文本Text
究竟是如何截斷顯示的, 跟隨著源碼一探究竟。
首先看到Text只是一個簡單的靜態(tài)組件StatelessWidget
從build方法中可以看到返回的是一個RichText,并將maxLines參數(shù)進行傳遞。
接著往下看RichText,可以看到RichText繼承了MultiChildRenderObjectWidget
多子渲染W(wǎng)idget,一定有創(chuàng)建渲染對象的地方。
通過createRenderObject對象返回 RenderParagraph
對象,并將maxLine參數(shù)繼續(xù)傳遞
點進去看一看,記住這個渲染對象
通過構造方法將參數(shù)傳遞給自身維護的私有成員變量 TextPainter
,這個對象是Flutter的文本繪制器,通過它來處理文本的布局與繪制,那繼續(xù)點進去看一看。
最終在布局和繪制方法時會觸發(fā)_createParagraphStyle
方法,返回ParagraphStyle
對象,這里的觸發(fā)時機就是上面渲染對象布局繪制時調(diào)用的,所以也可以理解TextPainter
就是Flutter框架渲染文本處理的封裝對象。
這個對象主要用來確定文本的段落樣式,而maxLines截取操作只會影響段落的顯示,并不會影響文本本身的樣式,這里判斷了是否設置了文本TextStyle樣式。如果沒有設置使用默認的樣式。 點進去看一看
最終通過構造方法觸發(fā)_encodeParagraphStyle
方法,文本屬性會直接通過和c++層交互進行保存,TextStyle和StrutStyle樣式的設置原理也一樣。最后通過渲染對象觸發(fā)layout方法確定文本繪制區(qū)域,也就是說設置maxLines之后文本內(nèi)容不會改變,但文本的繪制區(qū)域會發(fā)生改變。
解決方案
我們現(xiàn)在知道maxLine
本身是針對UI來進行截斷的,并不會改變設置的內(nèi)容屬性,如果想要獲取截斷后的文本數(shù)據(jù)我們該如何操作呢, 其實TextPainter
給我們提供了一些Api方法,我們可以直接使用。
通過didExceedMaxLines
方法我們可以判斷出,該文本是否超過最大行設置。
通過getPositionForOffset
可以返回一個TextPosition
對象,里面的offset
屬性就是我們需要的截斷后字符串在原始文本當中的index索引。
代碼:
class TextUtil { /// 獲取最大行文字字數(shù) static int calculateTextMaxTextPos(String value, double fontSize, {required double fontHeight, required double maxWidth, required EdgeInsetsGeometry padding, int maxLines = 3}) { final TextPainter painter = TextPainter( locale: WidgetsBinding.instance.window.locale, textDirection: TextDirection.ltr, maxLines: maxLines, strutStyle: StrutStyle(forceStrutHeight: true, fontSize: fontSize, height: fontHeight), text: TextSpan( text: value, style: TextStyle( height: fontHeight, fontSize: fontSize, ), ), textAlign: TextAlign.center); painter.layout(maxWidth: maxWidth - padding.horizontal); final didExceedMaxLines = painter.didExceedMaxLines; // print('是否超出最大行$didExceedMaxLines'); if (didExceedMaxLines) { final position = painter.getPositionForOffset(Offset( painter.width, painter.height, )); return position.offset; } return 0; } }
使用場景
有了這個方法,我們在一些產(chǎn)品需求為文字末尾添加展開收起的騷操作就非常的方便了,具體的封裝就留給你們啦,而且通過這種方式還可以計算電子書每頁數(shù)據(jù),也是非常的快速,同時也優(yōu)化了下之前模擬手勢翻頁電子書的計算。相較于之前計算文字高度計算量少了很多。
鏈接:booxfx 電子書模擬手勢翻頁。
到此這篇關于詳解Flutter如何獲取Text截斷后的字符串的文章就介紹到這了,更多相關Flutter獲取字符串內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android利用ShaderMask實現(xiàn)花里胡哨的文字特效
我們的?App?大部分時候的文字都是一種顏色,實際上,文字的顏色也可以多姿多彩。我們今天就來介紹一個能夠輕松實現(xiàn)文字漸變色的組件?——?ShaderMask,感興趣的可以了解一下2022-12-12Android編程ProgressBar自定義樣式之動畫模式實現(xiàn)方法
這篇文章主要介紹了Android編程ProgressBar自定義樣式之動畫模式實現(xiàn)方法,涉及Android動畫模式的布局技巧,非常具有實用價值,需要的朋友可以參考下2015-10-10Android開發(fā)中怎樣調(diào)用系統(tǒng)Email發(fā)送郵件(多種調(diào)用方式)
在Android中調(diào)用其他程序進行相關處理,幾乎都是使用的Intent,所以,Email也不例外,所謂的調(diào)用Email,只是說Email可以接收Intent并做這些事情2013-06-06Android隱私協(xié)議提示彈窗的實現(xiàn)流程詳解
這篇文章主要介紹了Android隱私協(xié)議提示彈窗的實現(xiàn)流程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-01-01Android App開發(fā)中HTTP擴展包OkHttp的入門使用指南
OkHttp包為安卓開發(fā)中基于HTTP協(xié)議的網(wǎng)絡編程提供了很大便利,這里我們就來看一下Android App開發(fā)中HTTP擴展包OkHttp的入門使用指南:2016-07-07優(yōu)化SimpleAdapter適配器加載效率的方法
下面小編就為大家?guī)硪黄獌?yōu)化SimpleAdapter適配器加載效率的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04