In this tutorial, you'll learn how to create a Kotlin function that automatically detects and colors Markdown-style bold text (surrounded by **) in an Android TextView. This is useful for formatting text dynamically without using HTML or multiple TextViews.

1. Problem Statement

Many apps need to format text dynamically, such as:

  • Highlighting titles or keywords in user-generated content
  • Applying custom styling to parts of a string
  • Supporting simple Markdown-like syntax in TextViews

Instead of using Spannable manually every time, we can create a reusable function that detects **text** and applies custom coloring.

2. Solution Overview

We’ll create a Kotlin extension function for TextView that:

  1. Finds all occurrences of **text** using regex
  2. Applies a custom color to the bold text
  3. Makes the ** markers invisible (transparent)

3. Implementation Steps

Step 1: Create the Kotlin Extension Function

Add this function to your project (e.g., in TextViewExtensions.kt):

```kotlin import android.graphics.Color import android.text.Spannable import android.text.SpannableString import android.text.style.ForegroundColorSpan import android.widget.TextView import androidx.annotation.ColorInt

/ * Applies a color to text wrapped in double asterisks (Markdown-style bold), * while making the asterisks transparent. * * @param color The color to apply to the bold text (e.g., ContextCompat.getColor(...)) */ fun TextView.colorMarkdownBoldText(@ColorInt color: Int) { val text = this.text.toString() if (text.contains("")) { val spannable = SpannableString(text) val regex = Regex("\\(.?)\\*") // Finds text

    // Apply color to each match
    regex.findAll(text).forEach { match ->
        val boldTextStart = match.range.first
        val boldTextEnd = match.range.last + 1 // +1 because range is inclusive

        // Color the text inside ** **
        spannable.setSpan(
            ForegroundColorSpan(color),
            boldTextStart,
            boldTextEnd,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        // Hide the ** markers by making them transparent
        spannable.setSpan(
            ForegroundColorSpan(Color.TRANSPARENT),
            boldTextStart,
            boldTextStart + 2, // First two chars (**)
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        spannable.setSpan(
            ForegroundColorSpan(Color.TRANSPARENT),
            boldTextEnd - 2,
            boldTextEnd, // Last two chars (**)
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
    }
    this.text = spannable
}

} ```

Step 2: Use the Function in Your Activity/Fragment

Call the function on any TextView:

```kotlin val textView = findViewById(R.id.textView) textView.text = "The Paradox of Choice\nDid you know that having too many options..."

// Apply color (e.g., from resources) textView.colorMarkdownBoldText(ContextCompat.getColor(this, R.color.purple_500)) ```

4. Advanced Customization

Make It Support More Markdown (Optional)

You can extend the function to handle other Markdown syntax, such as:

  • *italic* → Apply Typeface.ITALIC
  • ~~strikethrough~~ → Apply StrikethroughSpan

Example: kotlin // Inside the regex loop, add: spannable.setSpan( StyleSpan(Typeface.BOLD), // Makes text bold boldTextStart + 2, // Skip ** boldTextEnd - 2, // Skip ** Spannable.SPAN_EXCLUSIVE_EXCLUSIVE )

5. Performance Considerations

  • Regex overhead: If the text is very long, consider running this in a background thread.
  • Reusability: This works best for short, dynamic text. For long Markdown documents, use a library like Markwon.

7. Conclusion

With this approach, you can:

✅ Dynamically style **bold** text in TextView
✅ Keep code clean with an extension function
✅ Extend it for other Markdown features

This is useful for chat apps, note-taking apps, or anywhere you need simple text formatting without HTML.