Upgrade to Pro — share decks privately, control downloads, hide ads and more …

text spans: what, why and how?

text spans: what, why and how?

Avatar for Matheus Cassiano Candido

Matheus Cassiano Candido

September 05, 2017
Tweet

More Decks by Matheus Cassiano Candido

Other Decks in Programming

Transcript

  1. TextView Layout TextLine basic and global attrs: padding, margin, background,

    etc. also text selection and highlight. paragraph styling: bullet points, line breaking, line backgrounds. character level styling.
  2. bullet span val spacing = 20 // px! val items

    = arrayOf("Item 1", "Item 2", "Item 3") val builder = SpannableStringBuilder() items.forEach { val line = SpannableString(it) line.setSpan(BulletSpan(spacing), 0, it.length, SPAN_EXCLUSIVE_EXCLUSIVE) builder.appendln(line) } textView.text = builder
  3. quote span val quote = "I'm selfish,…” val author =

    "Marilyn Monroe" val quoteSpan = SpannableString(quote) quoteSpan.setSpan(QuoteSpan(), 0, quote.length, SPAN_EXCLUSIVE_EXCLUSIVE) val finalText = SpannableStringBuilder() finalText.appendln(quoteSpan) finalText.append(author) textView.text = finalText
  4. class CustomQuoteSpan : LeadingMarginSpan { val gap = 200 val

    quoteSize = 300 val leftQuote = "\u201C" val paint = TextPaint() init { paint.textSize = 240f } override fun drawLeadingMargin(canvas: Canvas, paint: Paint, x: Int, dir: Int, top: Int, baseline: Int, bottom: Int, text: CharSequence, start: Int, end: Int, first: Boolean, layout: Layout) { if ((text as Spanned).getSpanStart(this) == start) { canvas.drawText(leftQuote, x, top + quoteSize, this.paint) } } override fun getLeadingMargin(p0: Boolean): Int = gap } custom quote span
  5. custom quote span val quote = "I'm selfish,…” val author

    = "Marilyn Monroe" val quoteSpan = SpannableString(quote) quoteSpan.setSpan(CustomQuoteSpan(), 0, quote.length, SPAN_EXCLUSIVE_EXCLUSIVE) val finalText = SpannableStringBuilder() finalText.appendln(quoteSpan) finalText.append(author) textView.text = finalText
  6. alignment span //... val authorSpan = SpannableString(author) authorSpan.setSpan(AlignmentSpan.Standard(ALIGN_OPPOSITE), 0, author.length,

    SPAN_EXCLUSIVE_EXCLUSIVE) val finalText = SpannableStringBuilder() finalText .appendln(quoteSpan) .appendln() .append(authorSpan) textView.text = finalText
  7. foreground color span //... val selfish = "selfish" val impatient

    = "impatient" val insecure = "insecure" //... quoteSpan.setSpan(ForegroundColorSpan(myPinkColorInt), quote.indexOf(selfish), quote.indexOf(selfish) + selfish.length, SPAN_EXCLUSIVE_EXCLUSIVE) //... textView.text = builder
  8. relative size span //... val sureAsHell = "sure as hell"

    //... quoteSpan.setSpan(RelativeSizeSpan(1.5f), quote.indexOf(sureAsHell), quote.indexOf(sureAsHell) + sureAsHell.length, SPAN_EXCLUSIVE_EXCLUSIVE) //... textView.text = builder
  9. background color span //... quoteSpan.setSpan(BackgroundColorSpan(myPinkColor), quote.indexOf(sureAsHell), quote.indexOf(sureAsHell) + sureAsHell.length, SPAN_EXCLUSIVE_EXCLUSIVE)

    quoteSpan.setSpan(ForegroundColorSpan(myWhiteColor), quote.indexOf(sureAsHell), quote.indexOf(sureAsHell) + sureAsHell.length, SPAN_EXCLUSIVE_EXCLUSIVE) //... textView.text = builder
  10. custom typeface span class CustomTypefaceSpan(val typeface: Typeface) : MetricAffectingSpan() {

    override fun updateMeasureState(paint: TextPaint) { paint.typeface = typeface } override fun updateDrawState(paint: TextPaint) { paint.typeface = typeface } }
  11. custom typeface span //... val italicTypeface = ResourcesCompat .getFont(this, R.font.alegreya_italic)!!

    val boldTypeface = ResourcesCompat .getFont(this, R.font.alegreya_bold)!! quoteSpan.setSpan(CustomTypefaceSpan(italicTypeface), 0, quote.length, SPAN_EXCLUSIVE_EXCLUSIVE) authorSpan.setSpan(CustomTypefaceSpan(boldTypeface), 0, author.length, SPAN_EXCLUSIVE_EXCLUSIVE) textView.text = builder
  12. custom letter spacing span class LetterSpacingSpan(val spacing: Float) : CharacterStyle()

    { override fun updateDrawState(paint: TextPaint) { if (SDK_INT >= LOLLIPOP) paint.letterSpacing = spacing } } authorSpan.setSpan(LetterSpacingSpan(0.15f), 0, author.length, SPAN_EXCLUSIVE_EXCLUSIVE)
  13. clickable span class CustomClickSpan : ClickableSpan() { override fun onClick(view:

    View) { // action view.showToast("Clicked!", LENGTH_SHORT) } override fun updateDrawState(textPaint: TextPaint) { // do whatever with the textPaint textPaint.isUnderlineText = true } }
  14. image span val imageHolder = SpannableString(" ") val image =

    getDrawable(this, R.drawable.monroe) image.setBounds(0, 0, 100, 100) val imageSpan = ImageSpan(image, ImageSpan.ALIGN_BOTTOM) imageHolder.setSpan(imageSpan, 0, 1, SPAN_EXCLUSIVE_EXCLUSIVE) finalText .appendln(quoteSpan) .appendln() .append(authorSpan) .append(" ") .append(imageHolder) textView.text = finalText
  15. accessibility •the TtsSpan supplies extra information (meta-data) used for when

    text-to-speech is scanning •there are numerous types of TtsSpan •TYPE_DIGITS •TYPE_TELEPHONE •TYPE_TIME •TYPE_MONEY •and others
  16. span flags Flags control the span behavior of text inserted

    later (using the insert method for example).