安卓使用Span富文本给某段Text文本加上波浪线
生活随笔
收集整理的這篇文章主要介紹了
安卓使用Span富文本给某段Text文本加上波浪线
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言
最近項目需要給某段文字動態(tài)的加上波浪線,但是沒搜到什么好的方案,于是打算自己實現(xiàn)一下,效果如下:
正文
本文使用的方案是自定義Span富文本,并在Span中用貝塞爾曲線來繪制出波浪線
代碼如下:
import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.text.style.ReplacementSpan import com.lt.androidkj.utils.extend.dpFloat/*** creator: lt 2022/3/31 lt.dygzs@qq.com* effect : 波浪線富文本* [waveWidth]單個波浪線的寬,單位像素* [waveHeight]單個波浪線的高,單位像素* warning:*/ class WaveLineSpan(private val waveWidth: Float = 11.dpFloat(),private val waveHeight: Float = 4.dpFloat() ) : ReplacementSpan() {private val mStrokeWidth = 1.2.dpFloat()private val mPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {color = Color.BLACKstyle = Paint.Style.STROKEstrokeWidth = mStrokeWidth}private val mPath = Path()private var width = 0f//計算span的寬度override fun getSize(paint: Paint,text: CharSequence?,start: Int,end: Int,fm: Paint.FontMetricsInt?): Int {width = paint.measureText(text, start, end)return width.toInt()}override fun draw(canvas: Canvas,text: CharSequence?,start: Int,end: Int,x: Float,top: Int,y: Int,bottom: Int,paint: Paint) {//畫出textcanvas.drawText(text.toString(), start, end, x, y.toFloat(), paint)//四舍五入計算總個數(shù)val number = Math.round(width / waveWidth)//計算初始偏移,以使波浪線居中var xOffset = (width - number * waveWidth) / 2val y = y - mStrokeWidthval waveHeight = waveHeight + y//畫出貝塞爾曲線mPath.moveTo(x + xOffset, waveHeight)// 1.路徑對象Path.moveTo(x,y);//指定曲線的起點repeat(number) {mPath.quadTo(x + waveWidth / 2 + xOffset,y,x + waveWidth + xOffset,waveHeight)// 2.路徑對象.quadTo(控制點x,y,曲線的終點x,y);//繪制貝塞爾曲線xOffset += waveWidth}mPath.lineTo(x + xOffset,waveHeight)// 3.路徑對象.close();//path會默認閉合,使其閉合;lineTo不閉合canvas.drawPath(mPath, mPaint) // 4.繪制:畫布對象.drawPath(路徑對象,畫筆對象);} }//dp轉(zhuǎn)px,下面的app就是你的Application fun Number.dpFloat(): Float =this.toFloat() * app.resources.displayMetrics.density/*** 設(shè)置某一段文本具有底部波浪線*/ fun CharSequence.toWaveLineSpan(start: Int, end: Int, waveSize: Float = 11.dpFloat()): SpannableString {val s = if (this is SpannableString) this else SpannableString(this)s.setSpan(WaveLineSpan(waveSize),start, end,Spannable.SPAN_INCLUSIVE_EXCLUSIVE)return s }代碼都有注釋,邏輯很簡單,就是定義一個自己的Span,計算要畫的波浪線的寬度,并在相應(yīng)的寬高中用貝塞爾曲線api來畫一個個貝塞爾曲線
使用的代碼:
tv.text = "1234567890".toWaveLineSpan(3, 7)效果如下:
end
總結(jié)
以上是生活随笔為你收集整理的安卓使用Span富文本给某段Text文本加上波浪线的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: KMM Kotlin expect的几种
- 下一篇: Kotlin1.6.20好用的新特性:多