Theming and Customization
Introduction
TomTom Digital Cockpit supports theming of the UI. This enables IVI systems built on top of TomTom Digital Cockpit to have a customized look and feel which is aligned with the branding, make or model of the vehicle and which is consistent across the entire system. It also allows the system to support runtime theme switching, enabling the possibility of allowing the end-user to change the look of their UI while they are using their IVI system.
A theme is composed of styles which are divided into theme categories. Each category focuses on an aspect of the visual user interface such as colors or spacing between UI components. This page describes how to add themable UI controls and the theming system in detail.
How to Implement a Themable UI
TomTom's Digital Cockpit's theming mechanism makes use of Android's stylable XML attributes and Android styles. The rest of this guide assumes a basic understanding of these concepts.
A theme is divided into theme categories, each of which consists of a list of Android XML attributes which can be used to set the styling of a specific aspect of the UI, such as the color of some text. When implementing the UI, the developer can select attributes from the appropriate category instead of hardcoding a value into their layout XML.
Examples of the built-in theme categories include:
- TtThemeCategoryColors contains the possible common theme colors. This can be used to ensure similar parts of the UI such as the backgrounds of all panels of a certain type are the same color.
- TtThemeCategoryDimensSpacing contains the common spacing values in the theme. This can be used to ensure that all of the margin and padding values around similar UI controls such as the padding inside OK buttons is always the same.
- TtThemeCategoryDimensTextSize contains the common text sizes in the theme. This can be used to ensure that for example, all titles have the same size.
For example, inside TtThemeCategoryColors
, there is
1...2<!-- Used inside UI elements which require the most attention. -->3<attr name="tt_surface_content_color_emphasis_high" format="color" />4...5<!-- Used to indicate something is wrong. E.g., an error message in a text field. -->6<attr name="tt_surface_content_color_critical" format="color" />
As described by its documentation, the tt_surface_content_color_emphasis_high
attribute should be used when styling a UI content whose color should indicate to the user
that it is important. This attribute can be used as the value of android:textColor
when styling a TtTextView
. More detailed information on how
colors are organized in the theming system is available in the Color System
section.
For example, if we were adding an important title to the UI, this attribute could be used to set the text color:
1<com.tomtom.tools.android.api.uicontrols.textview.TtTextView2 android:id="@+id/importantTitle"3 android:layout_width="wrap_content"4 android:layout_height="wrap_content"5 android:text="Important Title"6 android:textAppearance="?attr/tt_display_text_style_l"7 android:textColor="?attr/tt_surface_content_color_emphasis_high" />
Alternatively, to style multiple buttons in the same way, the attribute can be used in an Android style:
1<style name="ImportantTextViewStyle">2 <item name="android:textColor">?attr/tt_surface_content_color_emphasis_high</item>3</style>45<style name="ImportantButtonStyle">6 <item name="android:textColor">?attr/tt_surface_content_color_emphasis_high</item>7</style>
The use of these attributes is core to ensuring that the entire UI of the IVI system is consistent and changes consistently when the end-user changes the UI theme at runtime.
To change the actual values of these attributes (and hence the look of the UI), see the section Customizing the Built-In Themes
TomTom Digital Cockpit also provides a UI controls library consisting of a number of UI controls that extend what is available by default in Android. These also help with producing a themable UI and it is advised to use them where possible.
Theme Attribute Naming Convention
The built-in Digital Cockpit themes are made up of a large number of styleable XML attributes.
These theme attributes follow a naming convention which help inform the developer of where they
should be used. The naming convention of theme attributes follows the
prefix_what_where_which_quality_quantity
format. Taking color attributes as an example, the
attribute names consist of:
prefix
for all attributes defined incore_theme
this istt
. The prefix for TomTom Digital Cockpit specific component attributes, which are defined inplatform_theming_api_common_attributes
isttivi
.what
determines the background color.where
determines the place where it is used. Optional.which
for all color attributes iscolor
.quality
represents the type of emphasis. Optional.quantity
determines the level of emphasis. Optional.
In the Color System section we'll explain how TomTom Digital Cockpit classifies background colors and emphasis, among other things, to achieve a coherent UI design.
Some examples for color attributes are:
Prefix | What | Where | Which | Quality | Quantity |
---|---|---|---|---|---|
tt | _primary | _color | |||
tt | _primary | _content | _color | _emphasis | _high |
tt | _primary | _content | _color | _emphasis | _medium |
tt | _primary | _content | _color | _emphasis | _low |
tt | _primary | _content | _color | _subdued | |
tt | _primary | _content | _color | _highlight | |
ttivi | _mainmenu | _content | _color | _emphasis | _high |
Note: All attributes defined within the same prefix_what_where_...
are called a group.
Global tokens
Most theme attributes refer to a very specific aspect of the UI such as the color of the content in a panel. However, some of the attributes in a theme have more of a global scope and refer to a general part of the UI. These attributes are referred to as global tokens or global attributes.
For certain global attributes the naming convention is based on a baseline value. The baseline value
is specified as the suffix of the attribute name, for example, it is the _1 in tt_size_1
.
The naming convention is composed of the following parts:
Prefix
for all attributes defined incore_theme
is_tt_
.Category
represents the global category.Scale
indicates the factor that the baseline value should be multiplied by to get to the final value. When the baseline value for the radiustt_radius_1
is 4dp, thett_radius_23
is therefore 4 * 23 = 92dp.
The common naming convention is applied for the following categories in the built-in themes:
Prefix | Category | Scale | Example |
---|---|---|---|
tt | _size | _1 | tt_size_1 |
tt | _spacing | _0.5 | tt_spacing_0.5 |
tt | _radius | _23 | tt_radius_23 |
tt | _icon_size | _2 | tt_icon_size_2 |
Customizing the Built-In Themes
TomTom Digital Cockpit comes with some pre-defined themes including a dark and a light theme. The theme can be customized by deriving a new theme from the existing one and overriding the existing values of these attributes in the new theme.
For example, to create new light and dark themes which are based on the build-in TomTom Digital Cockpit themes, the following XML can be used:
1<resources>2 <style name="MyProductLightTheme" parent="TtiviThemeColorLight">3 <!-- Define a new high emphasis content color for the light theme -->4 <item name="tt_surface_content_color_emphasis_high">@color/product_palette_blue</item>5 </style>67 <style name="MyProductDarkTheme" parent="TtiviThemeColorDark">8 <!-- Define a new high emphasis content color for the dark theme -->9 <item name="tt_surface_content_color_emphasis_high">@color/product_palette_red</item>10 </style>
All UI controls which use these attributes will get the defined value when the theme is changed.
The Theming System
TomTom Digital Cockpit's theming mechanism is heavily based on Android's theming approach, while additionally providing a means to switch themes at runtime through a service. The Android styles within the theme are applied to the context of the system UI. All the fragments hosted in the system UI will get that context with the correct styles applied. Similarly, when a theme changes at run-time, like when switching between light and dark mode themes, all views are created with a new context that has the new styles applied.
The theme is provided by the ThemingService
. This service is responsible for
deciding which theme should be used by the system UI. It loads the styles that themes can use from
all discoverable ThemeComponentProviderService
instances. (You can read more
on discoverable services in the documentation on
IviDiscoverableServiceIdProvider
.) You can add your own instances, or
replace the default one with custom instances that provide alternative styles.
Note: The ThemingService
works with IviTheme
s,
which are explained in detail in the Customization section.
The styles must provide values for all attributes within their respective categories. Failing to
do so will result in unexpected behavior as the views are missing some of their attributes. The
available attributes are defined within the
platform_theming_api_common_attributes
and core_theme
modules.
The core_theme
is a TomTomAndroidTools module which defines common theme attributes that can be
used in various projects. The platform_theming_api_common_attributes
module,
which extends core_theme
, also defines extra theme attributes for TomTom Digital Cockpit. You can customize
the visual appearance of your product by providing the desired values of these attributes.
If you want a look based on the TomTom UX design specification, you can use the
platform_theming_api_stock_theme
. This theme supports a light and a dark mode. The dark mode is
the default one for TomTom Digital Cockpit.
If you want a customized theme, you must add your own
ThemeComponentProviderService
to provide the extra styles for the
ThemingService
to discover. In that implementation you can override the
values of the platform_theming_api_stock_theme
to suit your look, or replace the
platform_theming_api_stock_theme
entirely.
Theming Design Concepts
Theme Categories
The appearance of the UI is determined by colors, margins, font types, etc. A theme is divided into categories for each of these aspects of the UI. To reduce duplication when creating a new theme and to be able to apply styles independently, these attributes are defined in categories like color, spacing, and font. Each category represents a set of attributes for the theme.
By having categories of theming attributes, you can create a slightly different theme based on any other theme. For example, you can create a new look by keeping all categories unchanged, except the color category. This way you do not need to duplicate all the attributes, but only attributes that you want to change.
The theme attributes are defined using the standard Android declare-styleable
. Some examples of
how categories are defined, and which categories attributes belong to, are:
1<!-- attrs_dimens_spacing.xml -->2<resources>3 <declare-styleable name="TtiviThemeCategoryDimensSpacing">4 <attr name="tt_spacing_1" format="dimension" />5 <attr name="tt_spacing_2" format="dimension" />6 <attr name="tt_spacing_3" format="dimension" />7 </declare-styleable>8</resources>910<!-- attrs.xml -->11<resources>12 <declare-styleable name="TtiviThemeCategoryStyles">13 <attr name="ttivi_navigation_search_input_text_appearance_style" format="reference" />14 </declare-styleable>15</resources>1617<!-- attrs_colors.xml -->18<resources>19 <declare-styleable name="TtiviThemeCategoryColors">20 <attr name="tt_surface_content_color_emphasis_high" format="color" />21 </declare-styleable>22</resources>
Color System
The color system helps you to apply colors to your UI, including your brand colors. Colors provide a hierarchy of information, give the correct meaning to UI elements, and meet legibility and contrast standards.
The TomTom Digital Cockpit color system is designed with a focus on: hierarchy, background colors, content colors, and emphasis.
Hierarchy
UI colors are based on the role they play in the interface. For example, the color of the surface will determine if the UI as a whole is light or dark.
By defining which colors can go on top of each other, you can ensure enough contrast to distinguish UI elements.
Background Colors

The background colors are classified into:
- Surface colors that affect the background of the components. The surface is the background of all panels, notifications, the process panel, etc.
- Primary colors that are used for primary actions like primary buttons.
- Secondary colors that are used for secondary actions like secondary buttons, the background of segmented controls, etc.
- Destructive and acceptance colors that are used for events that require immediate action or a decision of the user.
- Overlay color that is used for components that come on top of the surfaces such as overlays, pop-overs, etc.
- Main menu colors that are used for the active app icon, inactive icons, labels, and the background of the main menu.
- Control center colors that are used for elements in the control bar, and the background and system icons on top of it.
Content Colors

Content colors refer to the color of elements that are displayed on top of the background colors. Whenever UI elements such as texts or icons appear on top of these colors, they will have a different emphasis to create an order between them.
If there is selected content on the surface like a toggle button, then that selected state is part of a content color group.
Emphasis


A UI consists of many components. The fewer components, the easier it will be to understand what is being communicated. However, sometimes it cannot be avoided to have more components and then emphasis is used to make some of them stand out and become the focus of the user.
For important information and actions, a high emphasis color should be used. This prevents distractions from less important components in the UI, like a separation line. Those less important components could use a low emphasis color instead.
Emphasis is classified into:
- High emphasis which commands the most attention. High emphasis components may be accompanied by medium and low emphasis components that perform a less important role.
- Subdued state which is advised for a component that is not interactive, and as such should be de-emphasized. For example: dividers.
- Highlight state which communicates when a user has highlighted a component. It is usually combined with another, usually primary color. For example: a focused search view.
- Accent color which is used to indicate that some action is needed from the user, usually in combination with a highlight color. For example: an active state in a search view.
- Critical and success states which indicate errors and successful actions. For example: an invalid text in a text field.
- Alert, warning and caution which are used to raise the user’s attention. For example: a traffic warning on the planned route.
Customization
Here we'll dive deeper into the way you can customize your product using the tools that theming provides.
An IviThemeComponent
contains the necessary style information and it belongs
to a single IviThemeCategory
. The theme component styles are defined as
Android style resources. For
example, a Noto Sans font style is defined as:
1<resources>2 <style name="TtiviThemeFontNotoSans">3 <item name="tt_font_thin">@font/noto_sans_regular</item>4 <item name="tt_font_medium">@font/noto_sans_semi_bold</item>5 <item name="tt_font_bold">@font/noto_sans_bold</item>6 </style>7</resource>
A theme category, like color or font, is represented by an IviThemeCategory
.
They may contain multiple IviThemeComponent
s. For example, a font
IviThemeCategory
can have several font
IviThemeComponent
s, each for a different font.
An IviTheme
is a collection of IviThemeComponent
s.
A TtiviThemeCategoryPreset
is a pre-defined set of
IviThemeCategory
s.
An IviTheme
must contain at least one
IviThemeComponent
for each IviThemeCategory
listed
in the TtiviThemeCategoryPreset
. The ThemingService
has the responsibility to check this.
First you need to define styleable attributes for a category. Next you can define a style for it,
which will be used by an IviThemeComponent
later.
Let's use an example to demonstrate the creation of a custom theme. TomTom Digital Cockpit extends color
attributes like tt_surface_content_color_emphasis_high
which are defined in stock_theme
. It
is defined like this:
1<resources>2 <declare-styleable name="TtThemeCategoryColors">3 <attr name="tt_surface_content_color_emphasis_high" format="color" />4 </declare-styleable>5</resources>
And there is a default value for that color attribute in stock_theme
as well:
1<resources>2 <style name="TtThemeColorLight">3 <item name="tt_surface_content_color_emphasis_high">#2E3841</item>4 </style>5</resources>
The TomTom Digital Cockpit style TtiviThemeColorStock
inherits from the style TtThemeColorLight
and
there you can define the value you want for your theme:
1<resources>2 <style name="TtiviThemeColorStock" parent="TtThemeColorLight">3 <item name="tt_surface_content_color_emphasis_high">#A7B290</item>4 </style>5</resources>
Note: You can have multiple styles for the same theme category. For example, it is common to provide light and dark modes as user options. So you can define a light and a dark color theme, and let the user choose.
You can define a different value for the same attribute in another theme:
1<resources>2 <style name="TtiviThemeColorDark" parent="TtThemeColorDark">3 <item name="tt_surface_content_color_emphasis_high">#FFFFFF</item>4 </style>5</resources>
In code, the color category is defined as:
1enum class TtiviThemeCategoryPreset(val category: IviThemeCategory) {2 COLOR(IviThemeCategory("COLOR", StaticStringResolver("Color")))3}
Then the corresponding IviThemeComponent
s are created and provided by a
ThemeComponentProviderService
:
1class StockThemeComponentProviderService(2 iviServiceHostContext: IviServiceHostContext,3 serviceIdProvider: IviDiscoverableServiceIdProvider,4) : ThemeComponentProviderServiceBase(iviServiceHostContext, serviceIdProvider) {56 init {7 availableThemeComponents = listOf(8 with(TtiviThemeCategoryPreset.COLOR) {9 IviThemeComponent("Id", category, R.style.TtiviThemeColorStock, "Stock")10 },11 // Adding additional theme category flavors.12 with(TtiviThemeCategoryPreset.COLOR) {13 "Dark".let {14 IviThemeComponent("Id", category, R.style.TtiviThemeColorDark, it)15 }16 }17 )18 }19}
Finally an IviTheme
is created from the
ThemeComponentProviderService
:
1class StockThemingService(iviServiceHostContext: IviServiceHostContext) :2 ThemingServiceBase(iviServiceHostContext) {3 override fun onCreate() {4 super.onCreate()5 activeTheme = IviTheme(themeComponentProviderService.availableThemeComponents)6 }7}
If you want to slightly change the look, then you can change individual attribute values. If
you need to change the look dramatically, then you can create your own theme categories and
attributes and provide your own ThemeComponentProviderService to the
ThemeService
.