Styles & Themes

Repeating the same handful of view attributes across every screen — the same text size, color, and font weight on every recipe title, for instance — is exactly the kind of duplication resources exist to avoid. A style bundles those attributes into one reusable resource; a theme takes the same idea and applies it to an entire screen or app. This lesson covers both, and the important difference between them.

A Style: A Reusable Bundle of Attributes

RecipeBox shows a recipe's title in several places — the list screen, the detail screen, and the "add recipe" form's preview. Rather than repeating the same three attributes on every TextView, they're bundled once into a style:

<!-- res/values/styles.xml -->
<style name="RecipeTitleText">
    <item name="android:textSize">20sp</item>
    <item name="android:textColor">@color/recipe_green</item>
    <item name="android:textStyle">bold</item>
</style>

Applied to any TextView with a single attribute:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    style="@style/RecipeTitleText"
    android:text="@{recipe.title}" />
Explanation: Every TextView using style="@style/RecipeTitleText" stays visually consistent automatically. Bumping the title size later means editing this one <style> block, not hunting through every layout that shows a recipe title.

Style Inheritance with parent

A style can extend another style using the parent attribute, inheriting all of its attributes and only overriding what's different:

<!-- Extends a built-in Material text appearance, tweaking only the color -->
<style name="RecipeSubtitleText" parent="TextAppearance.Material3.BodyMedium">
    <item name="android:textColor">@color/recipe_text_secondary</item>
</style>
Explanation: RecipeSubtitleText keeps every default from Material's BodyMedium text appearance (correct size, letter spacing, line height for body text) and changes only the color — far less repetition than declaring all of that from scratch.

A Theme: A Style Applied to a Whole Screen or App

A theme is technically also a <style> resource, but it's applied differently — either to a single Activity, or to the entire app — via android:theme in AndroidManifest.xml, or app-wide by declaring it as the android:theme on the <application> tag:

<!-- AndroidManifest.xml (excerpt) -->
<application
    android:theme="@style/Theme.RecipeBox">

    <activity android:name=".RecipeDetailActivity"
        android:theme="@style/Theme.RecipeBox.Detail" />
</application>

Style vs. Theme: The Actual Difference

The two are easy to blur together, so it's worth stating plainly:

  • A style targets one view — apply RecipeTitleText to a TextView, and only that TextView is affected.
  • A theme sets defaults across an entire screen or app — including things an individual view has no control over at all, like the status bar color, the default text color for every TextView that doesn't specify one, or the app's default button style.
Common confusion: Trying to set the status bar color as a "style" on some view never works — it's a theme-level concern, controlled by attributes like colorPrimaryDark or android:statusBarColor inside a theme, not any individual widget.

themes.xml and the Required Material Parent

As covered in Material Components, Material widgets need the app's theme to descend from a Material base theme to render correctly:

<!-- res/values/themes.xml -->
<style name="Theme.RecipeBox" parent="Theme.Material3.DayNight.NoActionBar">
    <item name="colorPrimary">@color/recipe_green</item>
    <item name="colorSecondary">@color/recipe_orange</item>
</style>

Worked Example: A Per-Screen Theme Override

RecipeBox's recipe-detail screen uses a distinct Toolbar color from the rest of the app, without duplicating the whole theme — by declaring a small theme that extends Theme.RecipeBox and overrides just one attribute:

<!-- res/values/themes.xml (continued) -->
<style name="Theme.RecipeBox.Detail" parent="Theme.RecipeBox">
    <item name="colorPrimary">@color/recipe_orange</item>
</style>

Then, as shown in the manifest excerpt above, only RecipeDetailActivity declares android:theme="@style/Theme.RecipeBox.Detail" — every other Activity keeps the app-wide Theme.RecipeBox, unaffected.

Explanation: Because Theme.RecipeBox.Detail inherits from Theme.RecipeBox, it automatically keeps everything else (typography, other colors, the Material base) and only swaps the Toolbar's tint for this one screen.
Up next: Colors & Typography digs into colors.xml and text-size units in more depth.