Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android XML theme inheriting from two parent themes?

Android styles and themes always seem to make my head spin. I wanted to use the Holo UI across different versions of Android for my app. So I decided to extract the necessary resources by browsing the source.

I came across the following in android-15\data\res\values\themes.xml and I'm confused as to what exactly is being 'inherited' and from where:

<style name="Theme.Holo.Light" parent="Theme.Light">     ...     ... </style> 

The Android API Guide says :

If you want to inherit from styles that you've defined yourself, you do not have to use the parent attribute. Instead, just prefix the name of the style you want to inherit to the name of your new style, separated by a period.

But from the code above, it seems like Theme.Holo.Light is inheriting from Theme.Holo and from Theme.Light.

How does that work, or what am I not reading properly?

like image 519
Gautam Avatar asked Sep 27 '12 05:09

Gautam


People also ask

How do I change the default theme in Android Studio?

In Android Studio, open themes. xml (app > res > values > themes > themes.

Can we define themes in Android manifest?

You can create a theme the same way you create styles. The difference is how you apply it: instead of applying a style with the style attribute on a view, you apply a theme with the android:theme attribute on either the <application> tag or an <activity> tag in the AndroidManifest. xml file.

Can I make my own themes for Android?

Creating new themesOpen the Theme dropdown menu near the top of the right side of the Theme Editor. Click Create New Theme. In the New Theme dialog, enter a name for the new theme. In the Parent theme name list, click on the parent from which the theme inherits initial resources.


1 Answers

I've been wondering about this as well, so I wrote a simple test app to try it. Resources file looks like this:

<!--     Base application theme, dependent on API level. This theme is replaced     by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> <style name="AppBaseTheme" parent="android:Theme">     <!--         Theme customizations available in newer API levels can go in         res/values-vXX/styles.xml, while customizations related to         backward-compatibility can go here.     --> </style>  <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme">     <item name="android:windowNoTitle">true</item>     <item name="android:windowFullscreen">true</item>     <item name="android:windowContentOverlay">@null</item> </style>  <style name="AppTheme.TestTheme" parent="android:Theme.Light">  </style> 

So I apply AppTheme.TestTheme to the activity in the manifest file. AppTheme makes the window full-screen & not have a title bar. Theme.Light makes the window background light instead of the default dark. When the parent="android:Theme.Light" attribute is specified, the window is white and not fullscreen -- this means that the parent="..." attribute takes precedence over the name prefix, and the hierarchy appears to be TestTheme <- Theme.Light (light) <- Theme (dark).

With parent="android:Theme.Light" removed, the screen is dark and fullscreen, so the TestTheme <- AppTheme (fullscreen) <- AppBaseTheme <- Theme (dark) hierarchy is in place.

When parent="..." is specified, it makes no difference when I remove the prefix or not. So parent="..." seems to take definitely precedence. AppTheme.TestTheme does not inherit from both parents at once.

Now, looking at the default themes.xml, it seems that Theme.Holo.Light inherits from Theme.Light, and then all of the Holo stuff is specified manually in its description. So they named it Theme.Holo.Light not because it inherits from Holo, but because they wanted a name that describes it as 'the light version of Holo'. And because they wanted to be $@&!ing confusing.

This was tested on Gingerbread 2.3.3.

like image 58
Shitesh Avatar answered Oct 12 '22 15:10

Shitesh