Coloring Markdown-Style Bold Text in TextView
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:
- Finds all occurrences of
**text**
using regex - Applies a custom color to the bold text
- 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
// 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*
→ ApplyTypeface.ITALIC
~~strikethrough~~
→ ApplyStrikethroughSpan
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.