All those who have worked with styles and themes know that they’re hard to get right. We tend to get frustrated when we work with them. The hierarchy easily devolves into spaghetti code. How often did you want to change a style but feared you might break the continuity of the design of the app somewhere or the other.
I ran into a similar situation recently. I had to change the whole app’s style’s and theme by just changing the colors etc. in one location. This was for the Open Event android project where we wanted that while generating an apk by the apk generator we could change the color scheme of the app and could make it customisable for the needs of the organisations.
So, I’ll be talking about styling different views in this post. This shall be a long post!
When should we use styles
First of all, most of us get confused on when should we use styles instead of an inline attribute. Now I am going to show the rules that I follow:
When you have multiple views that should look identical ( Perhaps that do similar things)
Few Examples :
- Payment screens. You want to get the user through a bunch of ordering and payment screens. You need similar kind of buttons there to make it look like a continuous process. Hence we make the Buttons follow one particular style
<style name="Payment_Buttons"> <item name="android:minWidth">@dimen/button_min_width</item> <item name="android:minHeight">@dimen/button_min_height</item>
Try to use themes to tweak default styles
Themes provide a way of defining the default style of many widgets. For example :
If you want to define the default button for all of your payment screens in the example above, you can do something like :
<style name="ButtonTheme"> <item name="android:buttonStyle">@style/MyButton</item> </style>
But note that if you’re tweaking the default style, the only tricky part is to figure out the parent of your style but that’s really dificult due to a lot of variation within the different versions of android. If you’re using something that’s part of the AppCompat, then it’s okay. you don’t need to worry about the variations but when you want to style something not in AppCompat, then the main problem arises. So For example I want a button to be Holo until kitkat and then Material starting Lollipop, I’ll do something like this :
In values/styles.xml –
<style name="ButtonParent" Parent = "android:Widget.Holo.Button" />
<style name="ButtonParent.Holo"> <item name="android:background">@drawable/my_bg</item>
Then in values-v21/styles.xml:
<style name="ButtonParent" parent ="android:Widget.Material.Button/>
This makes the button consistent with guidelines and the app looks perfect.
Now, Themes vs Styles
This is a topic which most of the developers don’t know about. They get confused on what is the difference between them. I was also not totally clear about this until recently. A theme is infact a style, the only difference is the usage.
- We set a theme in the Manifest of the app or an activity
- We set a style in a layout file or a widget
- There are more styles than themes (Checkout styles.xml and themes.xml)
- Definition of a theme is in the essence jsut a collection of references to stlyes that the theme will use.
- To elaborate, let’s see the example of Theme.Holo :
It has a combination of
So, There can be different styles like this which can be referenced in a theme. Themes can be divided into 2 parts : General themes and sub themes
You can have a general them like Theme.ABC and if you want a variation of this general theme, for example no actionbar, you can add another theme like Theme.ABC.NoActionBar . This theme will not have the ActionBar
One of the interesting things that most people don’t know about is inhertance of styles/themes. What do I mean by this is that you can use existing styles and create some variations to suit different needs. There are 2 ways to use this inheritance. I’m going to try to explain and elorate on them :
- With a parent attribute
This is the most common way to use it and the way that most of the developers learn it while working on styles for the first time.
So how actually do we use it?
<style name = "Child" parent = "@style/Parent"> </style>
Here the child inherits all the properties of the style with the name “Parent” and define new properties in this style name “Child” where they can define new properties they want on top of the parent style.
2. With implicit style names
The other way to inherit styles/themes using the implicit way. Instead of setting a parent attribute, just prefix your new style/theme with the name of its parent and a dot. Something like this :
<style name = "Parent.Child"> </style>
This works the same as the previous method. Using this reduces some time to write additional parameter and is used by almost all experienced developers.
Plus you get some checks as well while writing code in Android studio. But be careful while using this as you need to take care of somethings :
- The Parent style/theme needs to exist, Otherwise an error
- You cannot inherit default themes and styles. For example you can’t create
<style name = "Theme.Holo.myTheme">
but you do this
<style name = "myTheme" parent = "Theme.Holo">
I know this can be overwhelming for a person who’s just starting with styles and themes. Trust me I was also not able to understand the concepts on the first go. I had to spend some time to grasp all that can be done using styles and themes. So I think this should be it for this blog. It’s already gotten pretty big.
Be sure to check out the Open event android project here and the usage of styles and themes there. Ciao till next time!