文本的描述中穿插图片更简单引起运用者的爱好和关注,Android中常运用的处理富文本的类,如SpannableString
、SpannableStringBuilder
等允许在字符串中运用不同的样式、色彩、字体作用等。
文本中穿插图片能够运用ImageSpan
或者DynamicDrawableSpan
来完成:
val content = "秋天,在不知不觉中,悄然到来。叶的飞去,不是由于风的追求,而是树的不款留!"
val tag = "秋天,在不知不觉中,悄然到来。"
val spannableString = SpannableString(content)
val index = content.indexOf(tag) + tag.length
val tag2 = "秋天"
val index2 = content.indexOf(tag2)
spannableString.setSpan(
BackgroundColorSpan(0x66000000),
index2,
index2 + tag2.length,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE
)
val drawable: Drawable? = ContextCompat.getDrawable(this, R.drawable.leaf)
drawable?.let {
it.setBounds(0, 0, PxUtil.dp2px(35f), PxUtil.dp2px(35f))
val imageSpan = ImageSpan(it)
spannableString.setSpan(imageSpan, index, index + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
}
r.tv1.text = spannableString
调查作用发现,图片切件与文本没有居中。ImageSpan
类有重载构造函数能够传递参数verticalAlignment
设置笔直对齐办法,但是ImageSpan.ALIGN_CENTER
有版本约束,并且即便传递该参数,图片与文本也没有笔直对齐。ImageSpan
承继自DynamicDrawableSpan
,DynamicDrawableSpan的draw办法中有对ALIGN_CENTER参数进行处理:
通过代码能够看到,绘制图片切件的时分只是根据当时显现规模进行了笔直居中,而并没有针对文本的显现进行居中处理。想要完成图片与文本在笔直方向上居中,能够自定义view,重写DynamicDrawableSpan的getSize
与draw
办法,自定义view完成作用如下:
class CenterVerticalImageSpan(
val context: Context,
private val resId: Int,
val width: Int,
val height: Int
) :
ImageSpan(context, resId) {
private var mDrawableRef: WeakReference<Drawable>? = null
override fun getSize(
paint: Paint,
text: CharSequence?,
start: Int,
end: Int,
fm: Paint.FontMetricsInt?
): Int {
val d: Drawable = getCachedDrawable()
val rect = d.bounds
fm?.let {
val fontHeight = it.descent - it.ascent
val fontCenterY = it.ascent + fontHeight / 2
val drawableHeight = rect.height()
// 重新设置文本方位
val ascentTop = it.ascent - it.top
it.top = fontCenterY - drawableHeight / 2
it.ascent = it.top + ascentTop
val descentBottom = it.bottom - it.descent
it.bottom = fontCenterY + drawableHeight / 2
it.descent = it.bottom - descentBottom
}
return rect.right
}
override fun draw(
canvas: Canvas,
text: CharSequence?,
start: Int,
end: Int,
x: Float,
top: Int,
y: Int,
bottom: Int,
paint: Paint
) {
val drawable = getCachedDrawable()
canvas.save()
val fm = paint.fontMetricsInt
val fontHeight = fm.descent - fm.ascent
val fontCenterY = y + fm.descent - fontHeight / 2
val transY = fontCenterY - drawable.bounds.height() / 2f
canvas.translate(x, transY)
drawable.draw(canvas)
canvas.restore()
}
override fun getDrawable(): Drawable {
val drawable: Drawable? = ContextCompat.getDrawable(context, resId)
drawable?.setBounds(0, 0, width, height)
?: run {
if (BuildConfig.DEBUG) {
throw RuntimeException("???")
}
}
return drawable!!
}
private fun getCachedDrawable(): Drawable {
val wr = mDrawableRef
var d: Drawable? = null
wr?.let {
d = it.get()
} ?: run {
d = drawable
mDrawableRef = WeakReference<Drawable>(d)
}
return d!!
}
}