Android
TextView
Bullet Symbol
Text Formatting
Android Development

How do I add a bullet symbol in TextView?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

TextView does not have a built-in list widget mode, but adding bullet points is still straightforward. The best approach depends on whether you only need a visible bullet character or whether you want proper paragraph indentation and richer text styling.

For small static text, a Unicode bullet is enough. For dynamic or better-formatted content, BulletSpan is usually the cleaner Android-native solution.

Use a Unicode Bullet for the Simplest Case

If you only need a short bulleted block, insert the Unicode bullet character directly into the text.

kotlin
1val lines = listOf(
2    "\u2022 First item",
3    "\u2022 Second item",
4    "\u2022 Third item",
5)
6
7textView.text = lines.joinToString("\n")

This works well when:

  • the content is short
  • you do not need hanging indentation
  • you are fine controlling line breaks yourself

It is also convenient for string resources because the rendered result is predictable and easy to localize.

Use BulletSpan for Better Paragraph Formatting

When bullets need to behave like formatted paragraphs rather than plain symbols, use a SpannableStringBuilder and attach BulletSpan to each item.

kotlin
1import android.graphics.Color
2import android.text.SpannableStringBuilder
3import android.text.Spanned
4import android.text.style.BulletSpan
5
6fun buildBulletedText(items: List<String>): CharSequence {
7    val builder = SpannableStringBuilder()
8
9    items.forEachIndexed { index, item ->
10      val start = builder.length
11      builder.append(item)
12      val end = builder.length
13
14      builder.setSpan(
15          BulletSpan(24, Color.DKGRAY),
16          start,
17          end,
18          Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
19      )
20
21      if (index != items.lastIndex) {
22          builder.append("\n")
23      }
24    }
25
26    return builder
27}
28
29textView.text = buildBulletedText(
30    listOf("Install dependencies", "Run the migration", "Restart the app")
31)

BulletSpan is paragraph-oriented formatting. In practice, each list item should be treated as its own paragraph segment, otherwise the span may not render as expected. That makes it a better tool than a raw bullet character when lines wrap or when indentation needs to look consistent.

HTML Is Acceptable When the Source Content Is Already HTML

If your content comes from a CMS or some stored rich text format, HTML parsing can be practical.

kotlin
1import androidx.core.text.HtmlCompat
2
3val html = """
4    <ul>
5      <li>Alpha</li>
6      <li>Beta</li>
7      <li>Gamma</li>
8    </ul>
9""".trimIndent()
10
11textView.text = HtmlCompat.fromHtml(
12    html,
13    HtmlCompat.FROM_HTML_MODE_LEGACY
14)

This is convenient when HTML already exists, but it is usually less direct than BulletSpan when the input is just a Kotlin list of strings. If the text is generated in app code, staying in spans often gives you clearer control.

Decide Based on the Layout Requirement

The decision is mostly about formatting behavior:

  • use a raw bullet character when you want the shortest possible solution
  • use BulletSpan when indentation and paragraph layout should look polished
  • use HTML only when your source content is already HTML

If you are rendering a long or interactive list, step back and consider whether a RecyclerView is the right component instead. A single TextView with bullets is best for short formatted copy, not for full-featured list screens.

Styling Details

BulletSpan lets you control useful layout details such as gap width and bullet color.

kotlin
val customSpan = BulletSpan(32, Color.parseColor("#1F4B99"))

If no explicit color is supplied, the bullet generally follows the current text color. You can also combine BulletSpan with other spans such as StyleSpan or ForegroundColorSpan to emphasize labels inside each paragraph.

Common Pitfalls

The biggest mistake is expecting a Unicode bullet to behave like a formatted list item when the text wraps across multiple lines. It is just a character, so alignment can look uneven. Another common issue is applying BulletSpan across the wrong text range. Since it is paragraph-oriented, it works best when each bullet item is separated cleanly.

Developers also sometimes parse HTML for text that is entirely generated in Kotlin. That works, but it adds unnecessary complexity. If the source data already exists as app strings, SpannableStringBuilder plus BulletSpan is usually easier to maintain.

Summary

  • Use a Unicode bullet for short, simple text.
  • Use BulletSpan when you want real paragraph-style bullet formatting.
  • 'HtmlCompat.fromHtml is reasonable only when your source content already exists as HTML.'
  • Keep each bullet item as its own paragraph segment when using BulletSpan.
  • Prefer a true list component instead of one large TextView when the content becomes long or interactive.

Course illustration
Course illustration

All Rights Reserved.