Table of Contents
Why Colors and Dimensions Matter
Design in Android apps is not only about making things look pretty. Colors and dimensions are part of your app's resources, and they help you keep the design consistent, easier to maintain, and adaptable to different devices.
In Android, you almost never hardcode colors or sizes directly into layouts or code. Instead, you define them as resources and then reference those resources wherever you need them. This chapter focuses on how to work with color and dimension resources in XML and how to use them correctly in layouts and code.
Always use color and dimension resources instead of hardcoded values. This makes your app easier to maintain, localize, theme, and adapt to different screens.
Color Resources: The Basics
Android stores color definitions in resource XML files, usually res/values/colors.xml. A color can represent solid colors, semi transparent colors, and even more complex definitions like color state lists, but in this chapter you will focus on simple color values.
A typical colors.xml file looks like this:
<resources>
<color name="colorPrimary">#6200EE</color>
<color name="colorPrimaryVariant">#3700B3</color>
<color name="colorOnPrimary">#FFFFFF</color>
<color name="colorSecondary">#03DAC6</color>
<color name="colorOnSecondary">#000000</color>
</resources>
Each color element has a name and a color value. The color value is usually a hexadecimal string that represents red, green, blue, and optional alpha (transparency).
A full ARGB value uses 8 hexadecimal digits in the format #AARRGGBB. For example, #FF6200EE has:
FFas alpha, fully opaque.62as red.00as green.EEas blue.
You can also omit the alpha part. A 6 digit value, for example #6200EE, is interpreted as fully opaque with alpha FF.
Use 8 digit #AARRGGBB values if you want explicit control over transparency. Use 6 digit #RRGGBB values when you want fully opaque colors.
Referring to Colors in XML Layouts
Once a color is defined in colors.xml, you can use it in your layout XML files by referencing its resource name with @color/.
For example, to set a background color on a TextView:
<TextView
android:id="@+id/titleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello"
android:textColor="@color/colorOnPrimary"
android:background="@color/colorPrimary" />
The @color/colorPrimary reference tells Android to look up the color named colorPrimary in your color resources.
You should avoid using raw hex color values directly in layouts, such as android:textColor="#FF0000". That makes changing colors later more difficult and breaks consistency if you reuse colors in many places.
Using Colors in Kotlin Code
You can also access color resources in your Kotlin code. There are several ways to do this. The modern approach uses the ContextCompat helper.
Inside an Activity you can write:
import androidx.core.content.ContextCompat
val primaryColor = ContextCompat.getColor(this, R.color.colorPrimary)
Inside a Fragment you can write:
val primaryColor = ContextCompat.getColor(requireContext(), R.color.colorPrimary)The result is an integer value that represents the color in ARGB format. You can then apply it to views, for example:
val textView: TextView = findViewById(R.id.titleText)
textView.setTextColor(primaryColor)
You should avoid hardcoding integer color values in your code. It is better to read them through the resource system using R.color.your_color_name.
Semantic Color Names
Color resources should not usually be named after their pure color like red, blue, or green. Instead, name them according to their role in your design.
For example, use names like colorPrimary, colorSecondary, colorError, colorOnPrimary, or buttonBackground. This makes it easier to change your color palette later without changing how your UI is structured.
If you change colorPrimary in one central place, the whole app updates automatically.
Use semantic names for colors that describe their purpose in the UI instead of their actual color value.
Light and Dark Variants of Colors
Modern Android apps typically support both light and dark themes. Even though the full theming system is covered separately, it is important to understand how color resources relate to that.
You can define separate color resources for light and dark themes using resource qualifiers, for example:
res/values/colors.xmlfor default (often light) colors.res/values-night/colors.xmlfor dark theme colors.
The two files define the same color names but assign different values.
Example res/values/colors.xml:
<resources>
<color name="backgroundColor">#FFFFFF</color>
<color name="textColorPrimary">#000000</color>
</resources>
Example res/values-night/colors.xml:
<resources>
<color name="backgroundColor">#000000</color>
<color name="textColorPrimary">#FFFFFF</color>
</resources>
When the system is in dark mode, Android automatically loads values from values-night. When in light mode, it uses values. Your layouts and code simply reference @color/backgroundColor and do not need to know which version is in effect.
Color State Lists (Preview Only)
Sometimes you want a color that changes depending on the view state, for example pressed or disabled. That is done with color state lists. The detailed explanation belongs elsewhere, but it is helpful to know that color resources can be more than just a single hex value.
A state list is defined in an XML file under res/color/, not res/values/. The mechanism allows you to keep visual feedback consistent across the app without hardcoding many states.
Dimension Resources: The Basics
Just like colors, dimensions are defined as resources, usually in res/values/dimens.xml. A dimension can represent lengths, sizes, margins, paddings, text sizes, and any other measurement.
A basic dimens.xml file looks like this:
<resources>
<dimen name="padding_small">8dp</dimen>
<dimen name="padding_medium">16dp</dimen>
<dimen name="padding_large">24dp</dimen>
<dimen name="text_size_small">12sp</dimen>
<dimen name="text_size_medium">16sp</dimen>
<dimen name="text_size_large">20sp</dimen>
</resources>
Each dimen element has a name and a value that includes a numeric amount plus a unit like dp or sp. The unit is essential. A plain number without a unit is not a valid dimension resource.
You should define most of your spacing and text sizes here instead of directly in layouts, so that you can change them globally and keep spacing consistent.
dp, sp, and Other Units
Android supports several units for dimensions. The most important for everyday layout work are dp and sp.
dp stands for density independent pixels. It is used for layout measurements such as widths, heights, margins, and paddings. The idea is that 1 dp represents the same physical size across devices with different screen densities, so your UI elements keep a consistent visual size.
sp stands for scale independent pixels. It is similar to dp but also respects the user's font size preference. You should use sp for text sizes, so that users who prefer larger or smaller text can see your app accordingly.
There are also px, pt, mm, and in, but in modern Android development you almost always prefer dp for layout and sp for text.
A very rough relationship between dp and pixels is:
$$ px = dp \times \frac{densityDpi}{160} $$
The densityDpi value depends on the device screen. You do not usually calculate this manually, but the formula explains why dp stays visually consistent on screens with different pixel densities.
Use dp for sizes, margins, and padding. Use sp for text sizes. Avoid using px directly.
Referring to Dimensions in XML Layouts
Once you have dimensions defined in dimens.xml, you can reference them in your layout files using @dimen/ followed by the resource name.
For example:
<TextView
android:id="@+id/titleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/padding_medium"
android:textSize="@dimen/text_size_large" />
Here android:padding uses a dp based value and android:textSize uses an sp based value. Both are loaded from the dimen resources.
This approach lets you reuse the same spacing and text sizes across multiple views. If design requirements change, you update one value in dimens.xml instead of editing many layout files.
Using Dimensions in Kotlin Code
You can also read dimension resources in code. There are two commonly used methods on Resources:
getDimension(R.dimen.some_dimen)returns the dimension as a float value in pixels.getDimensionPixelSize(R.dimen.some_dimen)returns the dimension as an integer number of pixels, rounded to the nearest pixel.
Inside an Activity you might write:
val paddingPx = resources.getDimensionPixelSize(R.dimen.padding_medium)
someView.setPadding(paddingPx, paddingPx, paddingPx, paddingPx)
Inside a Fragment:
val paddingPx = resources.getDimensionPixelSize(R.dimen.padding_medium)
view.setPadding(paddingPx, paddingPx, paddingPx, paddingPx)
You rarely want raw dp inside code. Instead you let Android convert your dp or sp values from dimens.xml into pixels for you.
Semantic Dimension Names and Scale
Just as with colors, dimension names should describe their role in your layout rather than the exact numeric value.
For spacing you might use names like spacing_xsmall, spacing_small, spacing_medium, spacing_large, and spacing_xlarge. For text you might use text_size_caption, text_size_body, text_size_title, or text_size_heading.
You can then decide that spacing_small is 8dp or 10dp without touching the layout files. Over time you may adjust your visual design by only changing the dimension resource values.
You can also define separate dimens.xml for different screen sizes using qualifiers. For example, you might have:
res/values/dimens.xmlfor default dimensions.res/values-sw600dp/dimens.xmlfor tablets and larger screens.
Each file defines the same names but with different values, so that the app automatically adapts to different screen sizes while layouts use the same resource names.
Avoiding Hardcoded Values
It is tempting to type quick numeric values in layouts, for example:
android:padding="16dp"
android:textSize="18sp"This is technically allowed, but it makes your code harder to maintain.
If that padding or text size appears in many places, you would need to update each occurrence manually when the design changes. Using @dimen/ with a shared dimension resource avoids this problem.
A better layout snippet is:
android:padding="@dimen/padding_medium"
android:textSize="@dimen/text_size_body"
You still use dp and sp, but only once in dimens.xml.
Avoid repeating the same numeric dp or sp values across many layout files. Put them in dimens.xml and reference them by name instead.
Combining Colors and Dimensions for Consistent Design
Colors and dimensions work together to create a coherent visual style. By centralizing both in resource files you gain several benefits.
You keep spacing and color usage consistent. For example, all buttons can use @color/buttonBackground and @dimen/button_corner_radius so they visually match everywhere.
You make themes easier to implement. When you later introduce light and dark themes, you can change color resources without touching layout files. Dimension resources can also be adjusted for different screen sizes or form factors.
You simplify collaboration. Designers can provide a list of colors and standard spacing rules, and you translate them into colors.xml and dimens.xml. Other developers then apply those names in layouts without memorizing exact values.
Over time, treating colors and dimensions as first class resources rather than one off values will help you build Android apps that are easier to maintain, style, and evolve.