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)
| Attribute | Purpose | Example |
|---|---|---|
| android:text | Actual content | "Hello, world!" |
| android:textSize | Size (sp) | 16sp, 20sp |
| android:textStyle | bold/italic | bold |
| android:textColor | Color | @color/black |
| android:fontFamily | Typeface | "sans-serif-medium" or @font/poppins |
| android:textAppearance | Theme-driven style | @style/TextAppearance.Material3.TitleLarge |
| android:maxLines | Limit lines | 1, 2, ... |
| android:ellipsize | Truncate | start|middle|end|marquee |
| android:autoSizeTextType | Auto-fit | uniform |
| android:drawableStart/End | Left/right icons (RTL-aware) | @drawable/ic_info |
| android:lineSpacingExtra|Multiplier | Leading | 4dp / 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
- Create a “Read more” TextView that shows 3 lines with ellipsize and toggles to full text on tap using a ClickableSpan.
- Build a settings section header style via textAppearance and apply it across multiple screens.
- Implement a marquee news ticker that starts automatically and pauses on user interaction.