Colors & Typography
Colors and text are the two things a user notices in the first half-second of looking at any screen. Android keeps both out of individual layouts and Java files as much as possible, centralizing them into resources instead — this lesson covers colors.xml, color state lists, custom fonts, and the unit Android uses for text size specifically.
colors.xml: One Palette, Defined Once
RecipeBox's entire palette — its primary green, an accent orange for calls to action, and its text colors — lives in a single file:
<!-- res/values/colors.xml -->
<resources>
<color name="recipe_green">#2E7D32</color>
<color name="recipe_orange">#EF6C00</color>
<color name="recipe_text_primary">#212121</color>
<color name="recipe_text_secondary">#757575</color>
</resources>
Why Not Just Hardcode the Hex Value?
Writing android:textColor="#2E7D32" directly on every TextView works, right up until RecipeBox's brand color needs to change. As covered in Resources Overview, the entire point of externalizing a value is having one place to update it — with a named color, changing the brand green means editing one line in colors.xml; with hardcoded hex values, it means hunting through every layout file that happens to use that shade, and almost certainly missing one.
Color State Lists: Colors That React to View State
Sometimes a single named color isn't enough — a button's text might need to look different when pressed versus disabled. A color state list, defined in res/color/, handles this by picking a different color per state:
<!-- res/color/button_text_color.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="@color/recipe_orange" />
<item android:state_enabled="false" android:color="@color/recipe_text_secondary" />
<item android:color="@color/recipe_text_primary" />
</selector>
Custom Fonts
RecipeBox applies a custom font to recipe titles for a bit of visual personality, either bundled directly as font files under res/font/, or fetched on demand through the Downloadable Fonts feature (which pulls the font from Google's font provider instead of shipping it in the APK). Either way, it's applied the same way — through a style:
<!-- res/values/styles.xml -->
<style name="RecipeTitleText">
<item name="android:fontFamily">@font/lobster_regular</item>
<item name="android:textSize">20sp</item>
<item name="android:textColor">@color/recipe_green</item>
</style>
Any TextView already using style="@style/RecipeTitleText" (introduced in Styles & Themes) picks up the new font automatically — no changes needed at each individual usage site.
Material's Typography Scale, Briefly
Material Design defines a small set of named text styles — display (large, short headlines), headline (screen and section titles), and body (regular paragraph text) — rather than leaving every text size as an arbitrary number. As mentioned in Material Components, these are available as ready-made styles like TextAppearance.Material3.HeadlineSmall, which RecipeBox's recipe-detail title and body text extend rather than defining sizes from scratch.
sp vs. dp: Why Text Size Is Different
Nearly every dimension in Android — margins, padding, icon sizes — is measured in dp (density-independent pixels), which scales consistently with screen density but stays fixed regardless of any user preference. Text size uses a different unit, sp (scale-independent pixels), and the difference matters for accessibility:
| Unit | Scales With Density | Respects User's Font-Size Setting |
|---|---|---|
| dp | Yes | No |
| sp | Yes | Yes |