In the previous article in this series on Android styling, we looked at the difference between themes and styles and how themes allow you to write more flexible styles and layouts which isolate changes:
Specifically we recommended using theme attributes to provide a point of indirection to resources, so that you can vary them (e.g. in dark theme). That is, if you find yourself writing a direct resource reference (or worse yet, a hardcoded value 😱) in a layout or style, consider if you should use a theme attribute instead.
1 |
|
common_theme_attrs_prefer.xml.diff hosted with ❤ by GitHub
But what theme attributes are available to use? This post highlights the common ones that you should know about; those that come from Material, AppCompat or the platform. This is not a complete list (for that I’d recommend browsing the attrs files linked below where they are defined) but these are the attributes that I use all the time.
Colors
Many of these colors come from the Material color system, which defines semantic names for colors that you can use throughout your app (implemented as theme attrs).
?attr/colorPrimary
The primary branding color for the app.?attr/colorSecondary
The secondary branding color for the app, usually a bright complement to the primary branding color.?attr/colorOn[Primary, Secondary, Surface etc]
A color which contrasts against the named color.?attr/color[Primary, Secondary]Variant
An alternate shade of the given color.?attr/colorSurface
A color for surfaces of components, such as cards, sheets, and menus.?android:attr/colorBackground
The background for the screen.?attr/colorPrimarySurface
switches betweencolorPrimary
in the Light themes,colorSurface
in the Dark theme.?attr/colorError
A color for displaying errors.
Other handy colors:
?attr/colorControlNormal
The color applied to icons/controls in their normal state.?attr/colorControlActivated
The color applied to icons/controls in their activated state (e.g. checked).?attr/colorControlHighlight
The color applied to control highlights (e.g. ripples, list selectors).?android:attr/textColorPrimary
The most prominent text color.?android:attr/textColorSecondary
Secondary text color.
Dimens
?attr/listPreferredItemHeight
Standard (min) height for list items.?attr/actionBarSize
The height of a toolbar.
Drawables
?attr/selectableItemBackground
A ripple/highlight for interactive items (also handy for foregrounds!!)?attr/selectableItemBackgroundBorderless
An unbounded ripple.?attr/dividerVertical
A drawable that may be used as a vertical divider between visual elements.?attr/dividerHorizontal
A drawable that may be used as a horizontal divider between visual elements.
TextAppearances
Material defines a type scale — a discrete set of text styles that you should use throughout your app, each of which is provided as a theme attribute which can be set as a textAppearance
. Check out the Material type scale generator to help generate a scale for different fonts.
?attr/textAppearanceHeadline1
defaults to light 96sp text.?attr/textAppearanceHeadline2
defaults to light 60sp text.?attr/textAppearanceHeadline3
defaults to regular 48sp text.?attr/textAppearanceHeadline4
defaults to regular 34sp text.?attr/textAppearanceHeadline5
defaults to regular 24sp text.?attr/textAppearanceHeadline6
defaults to medium 20sp text.?attr/textAppearanceSubtitle1
defaults to regular 16sp text.?attr/textAppearanceSubtitle2
defaults to medium 14sp text.?attr/textAppearanceBody1
defaults to regular 16sp text.?attr/textAppearanceBody2
defaults to regular 14sp text.?attr/textAppearanceCaption
defaults to regular 12sp text.?attr/textAppearanceButton
defaults to medium all caps 14sp text.?attr/textAppearanceOverline
defaults to regular all caps 10sp text.
Shape
Material employs a shape system which is implemented as theme attrs for small, medium and large components. Note that if you’re setting a shape appearance on a custom component, you likely want to use a MaterialShapeDrawable
as it’s background which understands and implements the shaping.
?attr/shapeAppearanceSmallComponent
used for Buttons, Chips, Text Fields etc. Defaults to rounded 4dp corners.?attr/shapeAppearanceMediumComponent
used for Cards, Dialogs, Date Pickers etc. Defaults to rounded 4dp corners.?attr/shapeAppearanceLargeComponent
used for Bottom Sheets etc. Defaults to rounded 0dp corners (i.e. square!)
Button Styles
This might seem super specific, but Material defines three types of buttons: Contained, Text and Outlined. MDC offers theme attrs that you can use to set the style
of a MaterialButton
:
?attr/materialButtonStyle
defaults to contained (or just omit the style).?attr/borderlessButtonStyle
for a text style button.?attr/materialButtonOutlinedStyle
for outlined style.
Floats
?android:attr/disabledAlpha
Default disabled alpha for widgets.?android:attr/primaryContentAlpha
The alpha applied to the foreground elements.?android:attr/secondaryContentAlpha
The alpha applied to secondary elements.
App vs Android namespace
You might have noticed that some attributes are referenced by?**android**:attr/foo
and others just by ?attr/bar
. This is because some are defined by the Android platform, and as such you need the android
part to reference them by their namespace (just like with view attributes in layouts: android:id
). Those without come from static libraries (i.e. AppCompat or MDC) which are compiled into your application, so don’t need the namespace (similar to how you might use app:baz
in a layout). Some elements are defined both in the platform and in a library e.g. colorPrimary
. In these cases, prefer the non-platform version, as this can be used on all API levels i.e. they’re duplicated in a library precisely to backport them. In these cases, I’ve listed the non-platform versions above.
prefer non-platform attributes which can be used on all API levels
More Resources
For a complete list of the theme attributes available to use, go to the source of truth:
Material Design Components:
Do It Yourself
Sometimes there isn’t a theme attribute which abstracts something you’d like to vary by theme. No worries… create your own! Here’s an example from the Google I/O app which shows a list of conference sessions in two screens.
Two screens listing conference sessions
They’re largely similar but the left screen must leave space for the sticky time headers while the right screen does not. We implemented this by abstracting where to align items behind a theme attribute so that we can vary them by theme and use the same layout across two different screens:
\1. Define the theme attribute in attrs.xml
1 | <!-- Copyright 2019 Google LLC. |
common_theme_attrs_custom_attr.xml hosted with ❤ by GitHub
\2. Provide different values in different themes:
1 | <!-- Copyright 2019 Google LLC. |
common_theme_attrs_custom_attr_values.xml hosted with ❤ by GitHub
\3. Use the theme attr in the single layout used on both screens (each using one of the above themes):
1 | <!-- Copyright 2019 Google LLC. |
common_theme_attrs_custom_attr_usage.xml hosted with ❤ by GitHub
Question (mark) everything
Knowing what theme attributes are available, equips you to use them when writing your layouts, styles or drawables. Using theme attributes makes it much easier to support theming (like dark theme) and to write more flexible, maintainable code. For a deep dive on this, join us in our next post in this series:
Android Styling: Prefer Theme AttributesTheme attribute all the thingsmedium.com
https://medium.com/androiddevelopers/android-styling-common-theme-attributes-8f7c50c9eaba