我們在需求開發(fā)的過程中误褪,往往會有計算文字寬度和高度的要求责鳍,遺憾的是Flutter并沒有提供計算文字寬/高的方法,無意中看到 Magic旭 大神的 Flutter-如何計算文字寬高 一文振坚,通過TextPainter
曲線救國來實現(xiàn)文字寬/高的計算薇搁,下面具體的實現(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;
}
通過上面的代碼相信大家應(yīng)該已經(jīng)看明白了其中的原理了,這個思路非常巧妙渡八,利用了TextPainter
類的layout()
方法來計算文字的寬/高啃洋。再深入layout()
的源代碼中可以看到最終是由ui.Paragraph
的layout()
調(diào)用native的方法完成寬度和高度計算的,如下圖:
TextPainter的layout()方法實現(xiàn)
ui.Paragraph的layout()方法實現(xiàn)
既然是由native的方法來計算寬度和高度的屎鳍,因此我們也可以得出宏娄,在不同的平臺上獲取到的字符串寬度和高度是不一樣的。但是同平臺不同的機型的計算結(jié)果是否會有差異呢逮壁?在Magic旭在文章中提到孵坚,在華為手機中遇到計算不準確的問題,需求傳入當(dāng)前的
Locale
對象才能準確計算窥淆,目前這個問題我還沒有遇到卖宠,希望各位遇到這個問題的同學(xué)在評論區(qū)反饋一下具體的機器型號和系統(tǒng)版本號,兼容華為手機的版本如下:
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;
}
兼容版本在上一個版本中增加了傳入Locale
對象忧饭,您可能會奇怪扛伍,為什么我不一開始就拿出來這個兼容版本呢,原因在于BuildContext
這個參數(shù)會大大限制使用的場景词裤,您可能會在項目中增加了一個GlobalStatic.context
這樣的全局變量刺洒,這樣就可以擺脫BuildContext
施加的場景限制了,這么做很好吼砂,沒有問題逆航。唯一不足的是限制了方法的移植性,方法粘貼到項目中還需要改造一下才能使用渔肩。因此綜合評估后因俐,我還是決定提供了一個移植性更好,但可能存在不足的方法,交由您來自己決定如何改造女揭。
結(jié)語
再次感謝Magic旭大神帶給我們的解決問題的方案和思路蚤假,最有價值的就是解決問題的思路,下面我們簡單回顧一下Magic旭大神的解題思路:
- 思考整個框架中哪里會有用到計算文字寬度和高度的地方吧兔,可以定位到
RichText
和Text
等組件磷仰,并從中選取一個閱讀代碼找答案。 - 在
RichText
組件可以找到TextPainter
境蔼,從TextPainter
中width
和height
變化的地方灶平,僅通過width
關(guān)鍵字就可以找到layout()
方法 - 寫Demo創(chuàng)建
TextPainter
,調(diào)用layout()
方法驗證自己的猜想箍土。
以上解題思路運用的好可以幫助我們解決很多開發(fā)過程中遇到的難題逢享,也是我們成為大神的必經(jīng)之路。