Table of contents
Introduction
This is an Android showcase project based on Pokémon.
The main goals of this project were to:
- Show how to create a design system compatible with multi-brand themes.
- Try Paparazzi, an open source snapshot testing library developed by Cash App team.
I chose to use Pokémon as an example because it was the perfect case of a multi-brand theme usage.
Since the first generation of games were released, they always used the idea of creating basically one base game, but with different themed variants for the game's boxes and cartridges, as well as some other contents.
Structure
.
├── app # Project sample (android-application)
├── buildSrc # Dependency management with Kotlin DSL
├── component # Design system components (android-libraries)
│ └── player
└── theme
├── base # Base theme and attributes (android-library)
└── brand # Brand theme implementations (android-libraries)
├── blue
├── green
├── red
└── yellow
Architecture
For the purpose of creating an actual sample, the project presents just one android-application module, which implements all four themes.
In the image above, it is presented a scenario where multiple apps were meant to be created, each one of them with its respective theme. In a real project, this would most likely be the case.
Implementation
This is a multi-module project and each piece have its own responsibility.
theme:base
Defines the custom attributes to be implemented by the theme:brand modules, as well as its base Android theme.
These attributes are like an interface: it doesn't have a value on its own, but defines a sort of contract to be implemented by whoever uses it.
<resources> <attr name="colorPrimary" format="color" /> <attr name="pokeImage" format="reference" /> resources>
Note: Besides your custom ones, you can also use attributes from a Material Theme, as can be seen here and here.
theme:brand:<name>
Implements the custom attributes declared in the theme:base module.
Each theme may have its own values, based on the design identity of given variant.
<resources>
<style name="PokemonRedTheme" parent="PokemonBaseTheme">
<item name="colorPrimary">#c62828item>
style>
resources>
component:<name>
Creates an Android custom view. Since this view is meant to be part of a multi-brand design system, it should almost always use the custom attributes from the theme:base, rather than setting hardcoded values.
"><gradient android:angle="?attr/angleGradient" android:endColor="?attr/colorPrimary" android:startColor="?attr/colorPrimaryVariant" />
Testing
Since one of the goals of this project was to try Paparazzi, only snapshot testing was explored.
Other ways of testing such as Espresso (as can be seen here) should also do the job.
Roadmap
- Add Compose.
- Add GitHub Actions.