Skip to content

Instantly share code, notes, and snippets.

@marcelpallares
Last active December 8, 2021 12:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcelpallares/ae6285ee0dcb3f04493991dcb18d01bd to your computer and use it in GitHub Desktop.
Save marcelpallares/ae6285ee0dcb3f04493991dcb18d01bd to your computer and use it in GitHub Desktop.
Creates a custom TextView to display ordered lists in a straightforward way. This is a modified solution from https://stackoverflow.com/a/27541189 to account for custom fonts and line spacing extra.
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.text.Layout
import android.text.SpannableStringBuilder
import android.text.style.LeadingMarginSpan
import android.util.AttributeSet
import android.widget.TextView
import androidx.appcompat.widget.AppCompatTextView
class OrderedListTextView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : AppCompatTextView(context, attrs) {
init {
setNumberedText(text.lines())
}
}
fun TextView.setNumberedText(list: List<String>) {
val content = SpannableStringBuilder()
val gap = context.resources.getDimensionPixelSize(R.dimen.margin_16)
list.forEachIndexed { index, text ->
val contentStart = content.length
content.appendLine(text)
content.setSpan(NumberIndentSpan(index + 1, gapWidth = gap), contentStart, content.length, 0)
}
text = content
}
class NumberIndentSpan(
private val number: Int,
private val leadWidth: Int = 15,
private val gapWidth: Int = 30,
) : LeadingMarginSpan {
override fun getLeadingMargin(first: Boolean): Int {
return leadWidth + gapWidth
}
override fun drawLeadingMargin(
canvas: Canvas,
paint: Paint,
x: Int,
dir: Int,
top: Int,
baseline: Int,
bottom: Int,
t: CharSequence?,
start: Int,
end: Int,
first: Boolean,
layout: Layout?
) {
if (first) {
val text = "$number."
val width = paint.measureText(text)
val yPosition = baseline.toFloat()
val xPosition = (leadWidth + x - width / 2) * dir
canvas.drawText(text, xPosition, yPosition, paint)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment