| Image by HalGatewood.com via Unsplash Copyright-free
WorldRemit underwent a rebrand in October 2020. For the Android team this posed a challenge to change the look of most of the app's components to better fit the new brand guidelines. This included colours (of icons, text etc.), shapes (of buttons, images etc), spacing between UI elements and fonts - so most things other than actual functionality.
How Android styling works
On Android, these kinds of things are mainly controlled in XML files - in one of three layers: layouts, styles and themes.
|Layout||A group of UI elements creating an interface for users to use that presents information and a way to interact with our services||~100s (roughly 1 for each screen or complex element)|
|Style||A group of attributes for a specific type of UI element||Approximately 50 ~ 100|
|Theme||Setting app-wide defaults: e.g. brand colours, fonts, how text looks at different sizes etc.||1 - 5|
Attributes can be specified in any of them, but a value in the upper layer overrides a value in the lower layer. Thus, setting the font of a piece of text in a style and layout will result in the value from the layout being used and the value from the style being ignored. Similarly, a value in the theme is only used if nothing is set in the style or layout for that value. So we get the following relationship:
Theme < Style < Layout
The End Goal
- Layouts with less repetition
- Styles that are re-usable
- A theme that can be switched out in future
As a team, we have set ourselves a goal of improving the stack at each level. We found some issues such as repetition in layouts which was most likely due to the developers being unable to find the styles they were looking for.
To try to tackle these problems, we wanted to take a bottom-up approach - start with the theme and work up to the layouts, improving the codebase and refactoring as we progressed. The problem was that it was very difficult to see the effect of the changes without the layout because it was ultimately displayed on the screen. To deal with this, we found an open source UI components sample app and combined it to our new themes and styles as they were developed, adding to the sample app as we progressed.
Buttons playground we made in the UI components sample app
Part 1: The theme
We started with the theme, opting for some brand colours that were required by Material Design themes such as
colorError, as well as some colors not as specific to the brand as choosing white and black for
colorError etc. are semantic names. They indicate the purpose of the colour rather than the colour itself. We did this to achieve our theme goal. In the future, if we decide to change the purple colour of our brand,then the names of colour usages all over the codebase will not need to be changed from
colorPrimary. Similarly, if we were to implement a dark mode, we would just need to switch
colorBackground to black and
colorOnBackground (frequently used in text for example) to white. This is much easier because it would not have to be changed wherever colours are used, but only in one place - the theme.
Part 2: Styles
Next, we started tackling styles with the aim of creating a style guide. Firstly, it required creating components with information detailing how they look and behave in our designer’s tool of choice. Starting with how text looks, then buttons as these are the most common two types of components. Then we moved on to text fields and less common components such as checkboxes, radio buttons and notifications. Where possible, we've tried preserve the look and feel of material design to speed up the development process and provide users with the high - quality user experience that our Android customers expect.
All of this is a style guide that can be applied to components in both design and development. After this was in place, designers and developers could use these standardised names rather than setting multiple properties in a custom way every time a component was added or changed on a screen - reducing copy/paste errors and producing a more consistent design language for the apps.
Part 3: Layouts
Thanks to our baseline variety of styles that can be applied to components, we could now refactor hundreds of pieces of code, making them simpler. As can be seen in the example code snippet below, these changes with semantically named styles mean that declarations of UI components in the layout can be easier to understand, and also do not require delving into the styles to understand what is happening. Frequently, specifically named styles like
Calculator.Totals.Title would have hidden properties within them that would be useful to know at the layout layer. These refactors helped drastically with layout goal - less repetition.
The work in the layouts layer is ongoing and the full migration will take some time. We have adopted the approach that when we changed the screen, we would refactor to use the new, rebranded, styles.
Having a well-structured design language improved the consistency and the look and the feel of the app on the screens. However, this change is not only beneficial to the users. It has improved the speed of communication between developers and designers and thus the time that screens can be developed. This is a change in approach which I would recommend investing time on for other front-end developers with similar problems in their codebase.