extended text 相關文章
- Flutter RichText支持圖片顯示和自定義圖片效果
- Flutter RichText支持自定義文本溢出效果
- Flutter RichText支持自定義文字背景
- Flutter RichText支持特殊文字效果
之前介紹過了Extended text,老規矩上圖
UI設計說,那個字可以加個卟呤卟呤閃閃的背景嗎? 當然可以啊,沒問題,我就去加,不就是TextStlye里面加個Background的嗎?
那個啥。。我的中文字呢?
又試了試,把背景色改成半透明的,中文字終于出來了,但是
尼瑪,這個頂部高亮是什么鬼
也不吐槽了,想看bug的去24335和24337 看看,這個問題是我發現,@吉原拉面 姐姐幫忙驗證,然后我們2個都開了issue,然后我的被關了,只剩下小姐姐的(有內情嗎)。那個我可以@吉原拉面 嗎,就是那個網紅程序猿 吉原拉面
對產品設計說
被慫為啥別人別的平臺能做啊,不管,必須支持。于是我又去看了下issue,去年的issue,都快4個月了。。搞什么鬼,修不修? 算了,不修,老夫自己來畫。。
文本里面加入圖片我們做過了那么一切好像都是順水成章的事情了。如果下面有哪里覺得講的有點跳躍,請先看之前的那篇文章,謝謝。
直接來到paint方法,還是循環找到BackgroundTextSpan
if (ts is BackgroundTextSpan) {var painter = ts.layout(_textPainter);Rect textRect = topLeftOffset & painter.size;Offset endOffset;if (textRect.right > rect.right) {int endTextOffset = textOffset + ts.toPlainText().length;endOffset = _findEndOffset(rect, endTextOffset);}ts.paint(canvas, topLeftOffset, rect, endOffset: endOffset);} else if (ts.children != null) {_paintSpecialTextChildren(ts.children, canvas, rect,textOffset: textOffset);}textOffset += ts.toPlainText().length;
復制代碼
這里我們要注意,因為你拿到的BackgroundTextSpan并且使用TextPainter出來的只能知道它整個文字的高度長度,不能直接知道它是否換行了,是否里面的文字是否文本溢出了,所以當文本最右邊大于整個文本的右邊的時候,就說明這個換行或者溢出了。使用_findEndOffset方法,我們從BackgroundTextSpan的最后一個字的位置向前找,直到找出BackgroundTextSpan最后一個不是文字溢出的位置
Offset _findEndOffset(Rect rect, int endTextOffset) {Offset endOffset = getOffsetForCaret(TextPosition(offset: endTextOffset, affinity: TextAffinity.upstream),rect,);//overflowif (endOffset == null || (endTextOffset != 0 && endOffset == Offset.zero)) {return _findEndOffset(rect, endTextOffset - 1);}return endOffset;}
復制代碼
找到之后就好辦了,如果endOffset為null,說明可以直接畫背景
canvas.drawRect(textRect, background);
復制代碼
否則就說明這個BackgroundTextSpan有換行。
paint(Canvas canvas, Offset offset, Rect rect, {Offset endOffset})
復制代碼
那么就分為三部分: 1.offset 到整個文本的最右邊 2.整行 3.整個文本的最左邊到endOffset
其實應該很好理解,通過下面的算法,計算出中間是否有整行
///endOffset.y has deviation,so we calculate with text height///print(((endOffset.dy - offset.dy) / _painter.height));var fullLinesAndLastLine =((endOffset.dy - offset.dy) / _textPainterHelper.painter.height).round();
復制代碼
剩下的就是繪畫了,詳見
到了這里,我們就已經解決掉了,中文字體和數字在一個TextSpan的時候Background的問題了。
但是這時候產品設計又來了,這是卟呤卟呤閃閃的背景?加個圓角可以不? 加個陰影可以不??
當然可以,什么東西我不能畫的,除了錢。。
于是我給BackgroundTextSpan加了clipBorderRadius圓角設置和paintBackground回調
///clip BorderRadiusfinal BorderRadius clipBorderRadius;///paint background by yourselffinal PaintBackground paintBackground;
復制代碼
圓角設置簡單。。之前我們不就做過了,詳見
PaintBackground 回調,給大家自己定義背景的機會。
if (backgroundTextSpan.clipBorderRadius != null) {canvas.save();canvas.clipPath(Path()..addRRect(backgroundTextSpan.clipBorderRadius.resolve(painter.textDirection).toRRect(fullLineRect)));}///draw full line canvas.drawRect(fullLineRect, backgroundTextSpan.background);if (backgroundTextSpan.clipBorderRadius != null) {canvas.restore();}
復制代碼
至于陰影,官方的BoxDecoration里面寫的很詳細,其實很多效果我都是看這個類才會的。。大家有空的話多看看源碼能得到不少啟示。
最后放上 Github Extended_Text,如果你有什么不明白的地方,請告訴我,歡迎加入Flutter Candies,一起生產可愛的Flutter 小糖果(QQ群:181398081)