詳解Flutter如何獲取Text截?cái)嗪蟮淖址?/h1>
更新時(shí)間:2023年06月12日 08:19:50 作者:老李code
當(dāng)Text文本設(shè)置maxLins屬性將文本強(qiáng)制截?cái)嘀?,Text的承載字符串是截?cái)嗲?,還是截?cái)嗪蟮哪兀覀冇衷撊绾潍@取截?cái)嗪蟮淖址?,下面就來和大家詳?xì)講講
問題
當(dāng)Text文本設(shè)置maxLins屬性將文本強(qiáng)制截?cái)嘀螅?code>Text的承載字符串是截?cái)嗲??還是截?cái)嗪蟮哪??我們?cè)撊绾潍@取截?cái)嗪蟮淖址兀?/p>
答案是:截?cái)嗲?截?cái)嘧址牟僮鞑⒉粫?huì)改變Text的真實(shí)文本內(nèi)容屬性,無論原生還是Flutter 截?cái)嘧址牟僮髦皇菍?duì)TextUI組件的繪制區(qū)域施加一個(gè)限制。
那么我們需要從源碼里看下當(dāng)我們?cè)O(shè)置了maxLine這個(gè)屬性以后,文本Text究竟是如何截?cái)囡@示的, 跟隨著源碼一探究竟。
首先看到Text只是一個(gè)簡(jiǎn)單的靜態(tài)組件StatelessWidget

從build方法中可以看到返回的是一個(gè)RichText,并將maxLines參數(shù)進(jìn)行傳遞。

接著往下看RichText,可以看到RichText繼承了MultiChildRenderObjectWidget多子渲染W(wǎng)idget,一定有創(chuàng)建渲染對(duì)象的地方。

通過createRenderObject對(duì)象返回 RenderParagraph對(duì)象,并將maxLine參數(shù)繼續(xù)傳遞

點(diǎn)進(jìn)去看一看,記住這個(gè)渲染對(duì)象

通過構(gòu)造方法將參數(shù)傳遞給自身維護(hù)的私有成員變量 TextPainter,這個(gè)對(duì)象是Flutter的文本繪制器,通過它來處理文本的布局與繪制,那繼續(xù)點(diǎn)進(jìn)去看一看。

最終在布局和繪制方法時(shí)會(huì)觸發(fā)_createParagraphStyle方法,返回ParagraphStyle對(duì)象,這里的觸發(fā)時(shí)機(jī)就是上面渲染對(duì)象布局繪制時(shí)調(diào)用的,所以也可以理解TextPainter就是Flutter框架渲染文本處理的封裝對(duì)象。


這個(gè)對(duì)象主要用來確定文本的段落樣式,而maxLines截取操作只會(huì)影響段落的顯示,并不會(huì)影響文本本身的樣式,這里判斷了是否設(shè)置了文本TextStyle樣式。如果沒有設(shè)置使用默認(rèn)的樣式。 點(diǎn)進(jìn)去看一看

最終通過構(gòu)造方法觸發(fā)_encodeParagraphStyle方法,文本屬性會(huì)直接通過和c++層交互進(jìn)行保存,TextStyle和StrutStyle樣式的設(shè)置原理也一樣。最后通過渲染對(duì)象觸發(fā)layout方法確定文本繪制區(qū)域,也就是說設(shè)置maxLines之后文本內(nèi)容不會(huì)改變,但文本的繪制區(qū)域會(huì)發(fā)生改變。
解決方案
我們現(xiàn)在知道maxLine本身是針對(duì)UI來進(jìn)行截?cái)嗟?,并不?huì)改變?cè)O(shè)置的內(nèi)容屬性,如果想要獲取截?cái)嗪蟮奈谋緮?shù)據(jù)我們?cè)撊绾尾僮髂兀?其實(shí)TextPainter給我們提供了一些Api方法,我們可以直接使用。
通過didExceedMaxLines方法我們可以判斷出,該文本是否超過最大行設(shè)置。
通過getPositionForOffset可以返回一個(gè)TextPosition對(duì)象,里面的offset屬性就是我們需要的截?cái)嗪笞址谠嘉谋井?dāng)中的index索引。
代碼:
class TextUtil {
/// 獲取最大行文字字?jǐn)?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ǎng)景
有了這個(gè)方法,我們?cè)谝恍┊a(chǎn)品需求為文字末尾添加展開收起的騷操作就非常的方便了,具體的封裝就留給你們啦,而且通過這種方式還可以計(jì)算電子書每頁數(shù)據(jù),也是非常的快速,同時(shí)也優(yōu)化了下之前模擬手勢(shì)翻頁電子書的計(jì)算。相較于之前計(jì)算文字高度計(jì)算量少了很多。
到此這篇關(guān)于詳解Flutter如何獲取Text截?cái)嗪蟮淖址奈恼戮徒榻B到這了,更多相關(guān)Flutter獲取字符串內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
-
Android利用ShaderMask實(shí)現(xiàn)花里胡哨的文字特效
我們的?App?大部分時(shí)候的文字都是一種顏色,實(shí)際上,文字的顏色也可以多姿多彩。我們今天就來介紹一個(gè)能夠輕松實(shí)現(xiàn)文字漸變色的組件?——?ShaderMask,感興趣的可以了解一下 2022-12-12
-
Android編程ProgressBar自定義樣式之動(dòng)畫模式實(shí)現(xiàn)方法
這篇文章主要介紹了Android編程ProgressBar自定義樣式之動(dòng)畫模式實(shí)現(xiàn)方法,涉及Android動(dòng)畫模式的布局技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下 2015-10-10
-
Android開發(fā)中怎樣調(diào)用系統(tǒng)Email發(fā)送郵件(多種調(diào)用方式)
在Android中調(diào)用其他程序進(jìn)行相關(guān)處理,幾乎都是使用的Intent,所以,Email也不例外,所謂的調(diào)用Email,只是說Email可以接收Intent并做這些事情 2013-06-06
-
Android隱私協(xié)議提示彈窗的實(shí)現(xiàn)流程詳解
這篇文章主要介紹了Android隱私協(xié)議提示彈窗的實(shí)現(xiàn)流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧 2023-01-01
-
使用ViewPager2實(shí)現(xiàn)簡(jiǎn)易輪播圖效果
這篇文章主要為大家詳細(xì)介紹了使用ViewPager2實(shí)現(xiàn)簡(jiǎn)易輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下 2022-09-09
-
Android App開發(fā)中HTTP擴(kuò)展包OkHttp的入門使用指南
OkHttp包為安卓開發(fā)中基于HTTP協(xié)議的網(wǎng)絡(luò)編程提供了很大便利,這里我們就來看一下Android App開發(fā)中HTTP擴(kuò)展包OkHttp的入門使用指南: 2016-07-07
-
優(yōu)化SimpleAdapter適配器加載效率的方法
下面小編就為大家?guī)硪黄獌?yōu)化SimpleAdapter適配器加載效率的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧 2017-04-04
最新評(píng)論
問題
當(dāng)Text文本設(shè)置maxLins屬性將文本強(qiáng)制截?cái)嘀螅?code>Text的承載字符串是截?cái)嗲??還是截?cái)嗪蟮哪??我們?cè)撊绾潍@取截?cái)嗪蟮淖址兀?/p>
答案是:截?cái)嗲?截?cái)嘧址牟僮鞑⒉粫?huì)改變Text的真實(shí)文本內(nèi)容屬性,無論原生還是Flutter 截?cái)嘧址牟僮髦皇菍?duì)TextUI組件的繪制區(qū)域施加一個(gè)限制。
那么我們需要從源碼里看下當(dāng)我們?cè)O(shè)置了maxLine這個(gè)屬性以后,文本Text究竟是如何截?cái)囡@示的, 跟隨著源碼一探究竟。
首先看到Text只是一個(gè)簡(jiǎn)單的靜態(tài)組件StatelessWidget

從build方法中可以看到返回的是一個(gè)RichText,并將maxLines參數(shù)進(jìn)行傳遞。

接著往下看RichText,可以看到RichText繼承了MultiChildRenderObjectWidget多子渲染W(wǎng)idget,一定有創(chuàng)建渲染對(duì)象的地方。

通過createRenderObject對(duì)象返回 RenderParagraph對(duì)象,并將maxLine參數(shù)繼續(xù)傳遞

點(diǎn)進(jìn)去看一看,記住這個(gè)渲染對(duì)象

通過構(gòu)造方法將參數(shù)傳遞給自身維護(hù)的私有成員變量 TextPainter,這個(gè)對(duì)象是Flutter的文本繪制器,通過它來處理文本的布局與繪制,那繼續(xù)點(diǎn)進(jìn)去看一看。

最終在布局和繪制方法時(shí)會(huì)觸發(fā)_createParagraphStyle方法,返回ParagraphStyle對(duì)象,這里的觸發(fā)時(shí)機(jī)就是上面渲染對(duì)象布局繪制時(shí)調(diào)用的,所以也可以理解TextPainter就是Flutter框架渲染文本處理的封裝對(duì)象。


這個(gè)對(duì)象主要用來確定文本的段落樣式,而maxLines截取操作只會(huì)影響段落的顯示,并不會(huì)影響文本本身的樣式,這里判斷了是否設(shè)置了文本TextStyle樣式。如果沒有設(shè)置使用默認(rèn)的樣式。 點(diǎn)進(jìn)去看一看

最終通過構(gòu)造方法觸發(fā)_encodeParagraphStyle方法,文本屬性會(huì)直接通過和c++層交互進(jìn)行保存,TextStyle和StrutStyle樣式的設(shè)置原理也一樣。最后通過渲染對(duì)象觸發(fā)layout方法確定文本繪制區(qū)域,也就是說設(shè)置maxLines之后文本內(nèi)容不會(huì)改變,但文本的繪制區(qū)域會(huì)發(fā)生改變。
解決方案
我們現(xiàn)在知道maxLine本身是針對(duì)UI來進(jìn)行截?cái)嗟?,并不?huì)改變?cè)O(shè)置的內(nèi)容屬性,如果想要獲取截?cái)嗪蟮奈谋緮?shù)據(jù)我們?cè)撊绾尾僮髂兀?其實(shí)TextPainter給我們提供了一些Api方法,我們可以直接使用。
通過didExceedMaxLines方法我們可以判斷出,該文本是否超過最大行設(shè)置。
通過getPositionForOffset可以返回一個(gè)TextPosition對(duì)象,里面的offset屬性就是我們需要的截?cái)嗪笞址谠嘉谋井?dāng)中的index索引。
代碼:
class TextUtil {
/// 獲取最大行文字字?jǐn)?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ǎng)景
有了這個(gè)方法,我們?cè)谝恍┊a(chǎn)品需求為文字末尾添加展開收起的騷操作就非常的方便了,具體的封裝就留給你們啦,而且通過這種方式還可以計(jì)算電子書每頁數(shù)據(jù),也是非常的快速,同時(shí)也優(yōu)化了下之前模擬手勢(shì)翻頁電子書的計(jì)算。相較于之前計(jì)算文字高度計(jì)算量少了很多。
到此這篇關(guān)于詳解Flutter如何獲取Text截?cái)嗪蟮淖址奈恼戮徒榻B到這了,更多相關(guān)Flutter獲取字符串內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android利用ShaderMask實(shí)現(xiàn)花里胡哨的文字特效
我們的?App?大部分時(shí)候的文字都是一種顏色,實(shí)際上,文字的顏色也可以多姿多彩。我們今天就來介紹一個(gè)能夠輕松實(shí)現(xiàn)文字漸變色的組件?——?ShaderMask,感興趣的可以了解一下2022-12-12
Android編程ProgressBar自定義樣式之動(dòng)畫模式實(shí)現(xiàn)方法
這篇文章主要介紹了Android編程ProgressBar自定義樣式之動(dòng)畫模式實(shí)現(xiàn)方法,涉及Android動(dòng)畫模式的布局技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-10-10
Android開發(fā)中怎樣調(diào)用系統(tǒng)Email發(fā)送郵件(多種調(diào)用方式)
在Android中調(diào)用其他程序進(jìn)行相關(guān)處理,幾乎都是使用的Intent,所以,Email也不例外,所謂的調(diào)用Email,只是說Email可以接收Intent并做這些事情2013-06-06
Android隱私協(xié)議提示彈窗的實(shí)現(xiàn)流程詳解
這篇文章主要介紹了Android隱私協(xié)議提示彈窗的實(shí)現(xiàn)流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-01-01
使用ViewPager2實(shí)現(xiàn)簡(jiǎn)易輪播圖效果
這篇文章主要為大家詳細(xì)介紹了使用ViewPager2實(shí)現(xiàn)簡(jiǎn)易輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09
Android App開發(fā)中HTTP擴(kuò)展包OkHttp的入門使用指南
OkHttp包為安卓開發(fā)中基于HTTP協(xié)議的網(wǎng)絡(luò)編程提供了很大便利,這里我們就來看一下Android App開發(fā)中HTTP擴(kuò)展包OkHttp的入門使用指南:2016-07-07
優(yōu)化SimpleAdapter適配器加載效率的方法
下面小編就為大家?guī)硪黄獌?yōu)化SimpleAdapter適配器加載效率的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04

