我們?cè)谛枨箝_(kāi)發(fā)的過(guò)程中,往往會(huì)有計(jì)算文字寬度和高度的要求,遺憾的是Flutter并沒(méi)有提供計(jì)算文字寬/高的方法,無(wú)意中看到 Magic旭 大神的 Flutter-如何計(jì)算文字寬高 一文,通過(guò)TextPainter曲線救國(guó)來(lái)實(shí)現(xiàn)文字寬/高的計(jì)算,下面具體的實(shí)現(xiàn)代碼:
static Size boundingTextSize(String text, TextStyle style, {int maxLines = 2^31, double maxWidth = double.infinity}) {
if (text == null || text.isEmpty) {
return Size.zero;
}
final TextPainter textPainter = TextPainter(
textDirection: TextDirection.ltr,
text: TextSpan(text: text, style: style), maxLines: maxLines)
..layout(maxWidth: maxWidth);
return textPainter.size;
}
通過(guò)上面的代碼相信大家應(yīng)該已經(jīng)看明白了其中的原理了,這個(gè)思路非常巧妙,利用了TextPainter類的layout()方法來(lái)計(jì)算文字的寬/高。再深入layout()的源代碼中可以看到最終是由ui.Paragraph的layout()調(diào)用native的方法完成寬度和高度計(jì)算的,如下圖:


既然是由native的方法來(lái)計(jì)算寬度和高度的,因此我們也可以得出,在不同的平臺(tái)上獲取到的字符串寬度和高度是不一樣的。但是同平臺(tái)不同的機(jī)型的計(jì)算結(jié)果是否會(huì)有差異呢?在Magic旭在文章中提到,在華為手機(jī)中遇到計(jì)算不準(zhǔn)確的問(wèn)題,需求傳入當(dāng)前的
Locale對(duì)象才能準(zhǔn)確計(jì)算,目前這個(gè)問(wèn)題我還沒(méi)有遇到,希望各位遇到這個(gè)問(wèn)題的同學(xué)在評(píng)論區(qū)反饋一下具體的機(jī)器型號(hào)和系統(tǒng)版本號(hào),兼容華為手機(jī)的版本如下:
static Size boundingTextSize(BuildContext context, String text, TextStyle style, {int maxLines = 2^31, double maxWidth = double.infinity}) {
if (text == null || text.isEmpty) {
return Size.zero;
}
final TextPainter textPainter = TextPainter(
textDirection: TextDirection.ltr,
locale: Localizations.localeOf(context, nullOk: true),
text: TextSpan(text: text, style: style), maxLines: maxLines)
..layout(maxWidth: maxWidth);
return textPainter.size;
}
兼容版本在上一個(gè)版本中增加了傳入Locale對(duì)象,您可能會(huì)奇怪,為什么我不一開(kāi)始就拿出來(lái)這個(gè)兼容版本呢,原因在于BuildContext這個(gè)參數(shù)會(huì)大大限制使用的場(chǎng)景,您可能會(huì)在項(xiàng)目中增加了一個(gè)GlobalStatic.context這樣的全局變量,這樣就可以擺脫BuildContext施加的場(chǎng)景限制了,這么做很好,沒(méi)有問(wèn)題。唯一不足的是限制了方法的移植性,方法粘貼到項(xiàng)目中還需要改造一下才能使用。因此綜合評(píng)估后,我還是決定提供了一個(gè)移植性更好,但可能存在不足的方法,交由您來(lái)自己決定如何改造。
結(jié)語(yǔ)
再次感謝Magic旭大神帶給我們的解決問(wèn)題的方案和思路,最有價(jià)值的就是解決問(wèn)題的思路,下面我們簡(jiǎn)單回顧一下Magic旭大神的解題思路:
- 思考整個(gè)框架中哪里會(huì)有用到計(jì)算文字寬度和高度的地方,可以定位到
RichText和Text等組件,并從中選取一個(gè)閱讀代碼找答案。 - 在
RichText組件可以找到TextPainter,從TextPainter中width和height變化的地方,僅通過(guò)width關(guān)鍵字就可以找到layout()方法 - 寫Demo創(chuàng)建
TextPainter,調(diào)用layout()方法驗(yàn)證自己的猜想。
以上解題思路運(yùn)用的好可以幫助我們解決很多開(kāi)發(fā)過(guò)程中遇到的難題,也是我們成為大神的必經(jīng)之路。