欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Span富文本自定义垂直对齐样式 - ReplacementSpan

程序员文章站 2022-03-04 09:07:26
###最近有个需求要实现这样的效果:&可能会想先Span改变字体大小,然后对齐方式设置:Top;然而尝试后并不行...so...#1 直接上效果:cc:我们默认情况下是向下对齐,我们需要自定义来改成对齐方式:#2自定义SuperSubSpan:class SuperSubSpan(private val type: SubSpanType = SubSpanType.DEFAULT) : ReplacementSpan() { override fun.....

###有个需求要实现这样的效果:

Android Span富文本自定义垂直对齐样式 - ReplacementSpan

这个时候,有写过添加上下标,这样就很好实现:我是传送门
 #效果:

Android Span富文本自定义垂直对齐样式 - ReplacementSpan

 #简单贴上代码:

private fun getSuperscriptSpanShow(): Spannable {
        val indexTH = TEXT_DATE.indexOf(TEXT_TH)
        val sb = SpannableStringBuilder(TEXT_DATE)
        //先更改TH的文本
        sb.setSpan(
            TextAppearanceSpan(this, R.style.DateTextTH),
            indexTH,
            indexTH + TEXT_TH.length,
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE
        )

        //将TH作为上标
        sb.setSpan(
            SuperscriptSpan(),
            indexTH,
            indexTH + TEXT_TH.length,
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE
        )
        return sb
    }

以上可以完全实现,如果要实现垂直对齐居中,好像就很麻烦了
&可能会想先Span改变字体大小,然后对齐方式设置:Center;然而尝试后并不行...
so...

#1 直接上效果:

Android Span富文本自定义垂直对齐样式 - ReplacementSpan

 cc:默认情况下是向下对齐,这里就需要自定义对齐方式

#2 自定义ReplacementSpan:

class SuperSubSpan(private val type: SubSpanType = SubSpanType.DEFAULT) : ReplacementSpan() {

    override fun getSize(
        paint: Paint,
        text: CharSequence,
        start: Int,
        end: Int,
        fm: Paint.FontMetricsInt?
    ): Int {
        val subText = text.subSequence(start, end)
        return paint.measureText(subText.toString()).toInt()
    }

    override fun draw(
        canvas: Canvas,
        text: CharSequence,
        start: Int,
        end: Int,
        x: Float,
        top: Int,
        y: Int,
        bottom: Int,
        paint: Paint
    ) {
        val subText = text.subSequence(start, end)
        val fm = paint.fontMetricsInt
        val subY = when (type) {
            SubSpanType.CENTER -> {
                (fm.descent - fm.ascent) + (y - (fm.descent - fm.ascent)) / 2
            }
            SubSpanType.TOP -> {
                fm.descent - fm.ascent
            }
            SubSpanType.DEFAULT -> {
                y
            }
        }
        canvas.drawText(subText.toString(), x, subY.toFloat(), paint)
    }
}

补充下:定义几个垂直方向的对齐类型

enum class SubSpanType {
    DEFAULT,
    TOP,
    CENTER
}

 cc:这里只是改变垂直对齐方式,并没有把字体,大小,颜色等封装进来。

#3 简单使用:

sb.setSpan(SuperSubSpan(type),startIndex, endIndex, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)

#4 Activity/Fragment 举例:

class MainActivity : AppCompatActivity() {

    companion object {
        private const val TEXT_DATE = "Jul 25th, 11:11am"
        private const val TEXT_TH = "th"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
    }

    private fun initView() {
        //Jul 23th
        text_sub_default.text = getDateSpanShow(SubSpanType.DEFAULT)
        text_sub_top.text = getDateSpanShow(SubSpanType.TOP)
        text_sub_center.text = getDateSpanShow(SubSpanType.CENTER)
    }

    private fun getDateSpanShow(type: SubSpanType): Spannable{
        val indexTH = TEXT_DATE.indexOf(TEXT_TH)
        val sb = SpannableStringBuilder(TEXT_DATE)
        sb.setSpan(
            TextAppearanceSpan(this, R.style.DateTextTH),
            indexTH,
            indexTH + TEXT_TH.length,
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE
        )

        sb.setSpan(
            SuperSubSpan(type),
            indexTH,
            indexTH + TEXT_TH.length,
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE
        )
        return sb
    }
}

以上就是 自定义对齐样式的 简单 实现!!!

###另外简单介绍下Spanable中的常用常量:

Spanned.SPAN_EXCLUSIVE_EXCLUSIVE -- 不包含start和end所在的端点              (a,b)

Spanned.SPAN_EXCLUSIVE_INCLUSIVE -- 不包含端start,但包含end所在的端点       (a,b]

Spanned.SPAN_INCLUSIVE_EXCLUSIVE -- 包含start,但不包含end所在的端点         [a,b)

Spanned.SPAN_INCLUSIVE_INCLUSIVE -- 包含start和end所在的端点                [a,b]

Spanable... 

>>Spannable

>>URLSpan/ClickableSpan

>>ImageSpan

本文地址:https://blog.csdn.net/qq_20613731/article/details/107476774