Flutter中計(jì)算文字的寬度/高度

我們?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.Paragraphlayout()調(diào)用native的方法完成寬度和高度計(jì)算的,如下圖:

TextPainter的layout()方法實(shí)現(xiàn)

ui.Paragraph的layout()方法實(shí)現(xiàn)

既然是由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旭大神的解題思路:

  1. 思考整個(gè)框架中哪里會(huì)有用到計(jì)算文字寬度和高度的地方,可以定位到RichTextText等組件,并從中選取一個(gè)閱讀代碼找答案。
  2. RichText組件可以找到TextPainter,從TextPainterwidthheight變化的地方,僅通過(guò)width關(guān)鍵字就可以找到layout()方法
  3. 寫Demo創(chuàng)建TextPainter,調(diào)用layout()方法驗(yàn)證自己的猜想。

以上解題思路運(yùn)用的好可以幫助我們解決很多開(kāi)發(fā)過(guò)程中遇到的難題,也是我們成為大神的必經(jīng)之路。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容