TextView (Java) — Typography, Links, Spans & Pro Tips

TextView is the most-used UI widget. Beyond simple text, it supports themes & styles, auto-sizing, ellipsizing, HTML, links, Spannable formatting/clicks, compound drawables (icons), and more.

What TextView can do (quick diagram)

textAppearance fontFamily autoSize ellipsize maxLines links HTML Spannable (color/bold/click) drawableStart/End lineSpacing hyphenation emoji RTL accessibility

Common Attributes (Cheat Sheet)

AttributePurposeExample
android:textActual content"Hello, world!"
android:textSizeSize (sp)16sp, 20sp
android:textStylebold/italicbold
android:textColorColor@color/black
android:fontFamilyTypeface"sans-serif-medium" or @font/poppins
android:textAppearanceTheme-driven style@style/TextAppearance.Material3.TitleLarge
android:maxLinesLimit lines1, 2, ...
android:ellipsizeTruncatestart|middle|end|marquee
android:autoSizeTextTypeAuto-fituniform
android:drawableStart/EndLeft/right icons (RTL-aware)@drawable/ic_info
android:lineSpacingExtra|MultiplierLeading4dp / 1.2

Example 1 — Title + Subtitle (Basics)

<!-- res/layout/tv_title_subtitle.xml -->
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:padding="12dp"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

  <TextView
      android:text="Welcome to CodingWithSonu"
      android:textStyle="bold"
      android:textSize="20sp" />

  <TextView
      android:text="Android tutorials in Java with clear examples."
      android:textColor="#555" />

</LinearLayout>

Example 2 — textAppearance & Theming (consistent typography)

<!-- res/values/styles.xml -->
<style name="App.Text.Title" parent="TextAppearance.Material3.TitleLarge">
  <item name="android:textColor">@color/black</item>
</style>
<!-- usage -->
<TextView
  android:text="Profile"
  android:textAppearance="@style/App.Text.Title" />
Why: textAppearance centralizes font size/weight/colors. Change once in styles → all TextViews update.

Example 3 — Auto-size (Responsive Headlines)

<TextView
  android:text="Responsive Headline That Shrinks"
  android:autoSizeTextType="uniform"
  android:autoSizeMinTextSize="12sp"
  android:autoSizeMaxTextSize="24sp"
  android:autoSizeStepGranularity="2sp"
  android:layout_width="match_parent"
  android:layout_height="wrap_content" />

Example 4 — MaxLines + Ellipsize (start/middle/end)

<TextView
  android:text="A very very long title that should truncate nicely in a single line"
  android:maxLines="1"
  android:ellipsize="end"
  android:layout_width="match_parent"
  android:layout_height="wrap_content" />

Example 5 — Marquee (Scrolling Text)

<TextView
  android:id="@+id/tvTicker"
  android:text="Breaking: New Android features are awesome… "
  android:ellipsize="marquee"
  android:marqueeRepeatLimit="marquee_forever"
  android:singleLine="true"
  android:focusable="true"
  android:focusableInTouchMode="true"
  android:scrollHorizontally="true" />
// Java: give focus so marquee starts
TextView tv = findViewById(R.id.tvTicker);
tv.setSelected(true); // or requestFocus()

Example 6 — Links: autoLink & custom click

<!-- Simple: auto-detect web/email/phone -->
<TextView
  android:text="Visit https://codingwithsonu.com or email info@codingwithsonu.com"
  android:autoLink="web|email"
  android:linksClickable="true" />
// Custom: clickable span
TextView tv = findViewById(R.id.tvCustom);
SpannableString s = new SpannableString("Tap here to open profile");
int start = 4, end = 8; // "here"
ClickableSpan cs = new ClickableSpan() {
  @Override public void onClick(View widget) { // open profile }
  @Override public void updateDrawState(TextPaint ds) {
    super.updateDrawState(ds);
    ds.setColor(Color.parseColor("#1b57e7"));
    ds.setUnderlineText(false);
  }
};
s.setSpan(cs, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(s);
tv.setMovementMethod(LinkMovementMethod.getInstance());
tv.setHighlightColor(Color.TRANSPARENT);

Example 7 — HTML formatting (basic)

// Java (basic HTML)
TextView tv = findViewById(R.id.tvHtml);
String html = "<b>Bold</b> and <font color='#1b57e7'>Blue</font>";
tv.setText(Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY));
Note: HTML support is limited to a subset. For full control, use Spannable.

Example 8 — Compound Drawables (icons with text)

<TextView
  android:text="Info"
  android:drawableStart="@drawable/ic_info"
  android:drawablePadding="8dp"
  android:gravity="center_vertical" />

Example 9 — Line spacing, letter spacing & hyphenation

<TextView
  android:text="Multi-line paragraph…"
  android:lineSpacingExtra="4dp"
  android:lineSpacingMultiplier="1.2"
  android:letterSpacing="0.02"
  android:hyphenationFrequency="full" />

Example 10 — Custom font from res/font

<!-- Place Poppins in res/font/poppins.ttf (or XML family) -->
<TextView
  android:text="Poppins font!"
  android:fontFamily="@font/poppins" />

Example 11 — Emoji & Internationalization (i18n)

  • TextView fully supports emoji: 😀 🎉 🇮🇳 (ensure your chosen font supports them)
  • Use @string resources for localization, and prefer start/end gravity over left/right for RTL.
<!-- res/values/strings.xml -->
<resources>
  <string name="hello_emoji">Hello 👋, Namaste!</string>
</resources>

Example 12 — Accessibility (content descriptions & contrast)

  • Ensure sufficient color contrast (textColor vs background).
  • If the TextView is acting as a button, consider using a real Button or set focusable and clickable appropriately.
  • For icons next to text, the text already describes the control; contentDescription on TextView is typically not needed unless it’s an icon-only view.

Example 13 — Dynamic span styling (bold & colored range)

// Java: multiple spans
TextView tv = findViewById(R.id.tvSpan);
SpannableString s = new SpannableString("New version 2.0 available!");
s.setSpan(new StyleSpan(Typeface.BOLD), 12, 15, 0); // "2.0"
s.setSpan(new ForegroundColorSpan(Color.parseColor("#D32F2F")), 0, 3, 0); // "New"
tv.setText(s);

Example 14 — Measuring & getting text (for logic)

// Java
TextView tv = findViewById(R.id.tvInfo);
String current = tv.getText().toString();
int lines = tv.getLineCount(); // after layout

Performance & Best Practices

  • Use sp for text size (respects user font scale).
  • Prefer textAppearance for consistency; avoid inlining styles everywhere.
  • For long lists, don’t place hundreds of TextViews in a ScrollView—use RecyclerView.
  • Cache expensive Spannables if reused (e.g., in adapters).
  • Use start/end for layout & drawables to be RTL-ready.

Practice Tasks

  1. Create a “Read more” TextView that shows 3 lines with ellipsize and toggles to full text on tap using a ClickableSpan.
  2. Build a settings section header style via textAppearance and apply it across multiple screens.
  3. Implement a marquee news ticker that starts automatically and pauses on user interaction.