27

I found a way to create TypeFaceSpan from TypeFace like this :

fun getTypeFaceSpan(typeFace:TypeFace) = TypeFaceSpan(typeFace)

But this API is allowed only in API level >= 28 . Any Compat libray to achieve this below 28?

erluxman
  • 18,155
  • 20
  • 92
  • 126

2 Answers2

48

TypeFaceSpan is a MetricAffectingSpan. So even if there is not any exact way to get TypeFaceSpan from Span, we can make CustomTypeFaceSpan like below and use it in place of TypeFaceSpan.

class CustomTypefaceSpan(private val typeface: Typeface?) : MetricAffectingSpan() {
    override fun updateDrawState(paint: TextPaint) {
        paint.typeface = typeface
    }

    override fun updateMeasureState(paint: TextPaint) {
        paint.typeface = typeface
    }
}

And Use it like this :

val typeFaceSpan = CustomTypefaceSpan(typeface)
erluxman
  • 18,155
  • 20
  • 92
  • 126
1

Inspired on the answer from @erluxman and combining with Kotlin's extension functions:

fun Typeface.getTypefaceSpan(): MetricAffectingSpan {
    return if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.P) typefaceSpanCompatV28(this) else CustomTypefaceSpan(this)
}

@TargetApi(Build.VERSION_CODES.P)
private fun typefaceSpanCompatV28(typeface: Typeface) =
    TypefaceSpan(typeface)


private class CustomTypefaceSpan(private val typeface: Typeface?) : MetricAffectingSpan() {
    override fun updateDrawState(paint: TextPaint) {
        paint.typeface = typeface
    }

    override fun updateMeasureState(paint: TextPaint) {
        paint.typeface = typeface
    }
}

then you can use it like this:

typeface.getTypefaceSpan()
Alécio Carvalho
  • 13,481
  • 5
  • 68
  • 74