styles multiple inheritance - android

Is there any way to make a style inherit from multiple other styles, instead of just being limited to:
<style name="WidgetTextBase">
<item name="android:typeface">serif</item>
<item name="android:textSize">12dip</item>
<item name="android:gravity">center</item>
</style>
<style name="BOSText" parent="WidgetTextBase">
<item name="android:textColor">#051C43</item>
</style>
I would like BOSText to also inherit from:
<style name="WidgetTextHeader">
<item name="android:textStyle">bold</item>
<style>

Styles do not support multiple inheritance (at least not as of Android 3.2).
The official docs say:
If you use the dot notation to extend a style, and you also include
the parent attribute, then the parent styles override any styles
inheritted through the dot notation.

You can only inherit one style. However, you can also make the inherited style inherit from another style, and so on:
<style name="WidgetTextBase">
<item name="android:typeface">serif</item>
<item name="android:textSize">12dip</item>
<item name="android:gravity">center</item>
</style>
<style name="WidgetTextHeader" parent="WidgetTextBase">
<item name="android:textStyle">bold</item>
</style>
<style name="BOSText" parent="WidgetTextHeader">
<item name="android:textColor">#051C43</item>
</style>
You can't inherit more than one style, but you can set up an inheritance chain.

For those who was looking for solution to just merge multiple different styles into one, you can use
public void applyStyle (int resId, boolean force)
https://developer.android.com/reference/android/content/res/Resources.Theme#applyStyle(int,%20boolean).
And apply it that way
context.theme.applyStyle(R.style.MyAdditionalStyle, false)
Whenever you specify true as second argument, it overrides existing values in your theme, and when false it adds only non-overlapping values from R.style.MyAdditionalStyle
I haven't tested scenario with multiple styles yet, but according to docs you can achieve it. So that's how this approach can be used as an alternative to multiple inheritance.

There is a parent attribute on the style tag that should let you inherit from other styles...
i.e.
<style name="CodeFont" parent="#style/WidgetTextBase">
<item name="android:textStyle">bold</item>
</style>
http://developer.android.com/guide/topics/ui/themes.html

Related

How to use custom parents in Android style.xml file?

In my android app I make use of styles in the style.xml. I have this one
<style name="EditText" parent="#android:style/Widget.EditText">
<item name="android:gravity">center</item>
<item name="android:textColor">#000000</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">#drawable/bg_edit_text</item>
</style>
But now I have another one, and I want the parent to be the code above. If I try
parent="#android:style/EditText"
it says it can't be found. Does anyone know how it's done?
Thanks
Your EditText style is a custom style so putting #android:style/ will not work. Based on the android documentation on style inheritance, you can directly specify the name
parent="EditText"
or specify it in the name attribute without using the parent attribute
name="EditText.YourNewStyleName
http://developer.android.com/guide/topics/ui/themes.html#Inheritance

Overwrite only changed style properties for Android fragmentation

I define the followiung style in values/styles.xml of my application:
<style name="light_textview_style">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginTop">#dimen/_1_BU</item>
<item name="android:textColor">#color/login_text</item>
<item name="android:textSize">#dimen/text_1_and_quarter_BU</item>
</style>
And in my values-xlarge/styles.xml I modify it the following way:
<style name="light_textview_style">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginTop">#dimen/_1_BU</item>
<item name="android:textColor">#color/login_text</item>
<item name="android:textSize">#dimen/text_1_and_quarter_BU</item>
</style>
Basically changing only one property - layout_width becomes wrap content for large displays.
I have many such cases of styles. This means that I duplicate a huge number of properties between styles because of fragmenting just few properties.
Is there any cleverer way to reuse the declaration from values/styles.xml and specify explicitly only the changed properties?
You can have the parent style and derive two different styles from it.
Look at this link about: themes

what does an item without namespace mean in style

<style name="Widget.Styled.ActionBar" parent="Widget.Sherlock.Light.ActionBar.Solid.Inverse">
<item name="background">#drawable/bg_action_bar</item>
<item name="android:background">#drawable/bg_action_bar</item>
<item name="android:textColor">#color/my_red</item>
</style>
<style name="My_Style" parent="style/Theme.Sherlock.Light">
<item name="android:actionBarStyle">#style/ActionBar</item>
<item name="android:homeAsUpIndicator">#drawable/ic_action_back</item>
<item name="homeAsUpIndicator">#drawable/ic_action_back</item>
</style>
What is the difference between 'homeAsUpIndicator' and 'android:homeAsUpIndicator' or 'background' and 'android:background' ?
I wonder if I need to set them both? I just found these examples, but could not find what you are setting when you don't use the 'android' namespace...
Due to limitations in Android's theming system any theme
customizations must be declared in two attributes. The normal
android-prefixed attributes apply the theme to the native action bar
and the unprefixed attributes are for the custom implementation. Since
both theming APIs are exactly the same you need only reference your
customizations twice rather than having to implement them twice.
The easiest way to convey exactly what this entails is with an example. The following is the full theme from the “Styled” example mentioned above:
<style name="Theme.Styled" parent="Theme.Sherlock.Light.DarkActionBar">
<item name="actionBarStyle">#style/Widget.Styled.ActionBar</item>
<item name="android:actionBarStyle">#style/Widget.Styled.ActionBar</item>
</style>
Read more about ActionbarSherlock's Mirrored Attributes

Set a consistent style to all EditText (for e.g.)

I'm trying to make all EditText's in my application have a consistent look. I'm aware that I can do something like this:
<style name="App_EditTextStyle">
<item name="android:background">#drawable/filled_roundededges_box_dark</item>
<item name="android:textColor">#808080</item>
<item name="android:layout_height">45dip</item>
</style>
Then I can make a particular EditText have this style by doing this:
<EditText ...
style="#style/App_EditTextStyle
...>
But this way I have to remember to set the style individually for each and every EditText in my application which is tedious, if not error prone.
Is there some way I could make this a part of a theme or something? This is so I don't have to associate this style to every EditText. Something like this fictitious code block:
<style name="App_Theme" parent="#android:style/Theme.Holo">
...
<item name="android:EditTextSyle">#style/App_EditTextStyle</item>
...
<style>
And then in my AndroidManifest.xml I have something like:
<application
....
android:theme="#style/App_Theme">
And Voila! all my EditText's have the consistent style without me having to specify the style for each instance.
Override the attribute pointing to the EditText style(named editTextStyle :) ) in your custom theme:
<style name="App_Theme" parent="#android:style/Theme.Holo">
<item name="android:editTextStyle">#style/App_EditTextStyle</item>
</style>
and make your custom style to extend Widget.EditText:
<style name="App_EditTextStyle" parent="#android:style/Widget.EditText">
<item name="android:background">#drawable/filled_roundededges_box_dark</item>
<item name="android:textColor">#808080</item>
<item name="android:layout_height">45dip</item>
</style>
Edit:
If you're using the much newer AppCompat related themes use the editTextStyle attribute without the android prefix:
<style name="App_Theme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="editTextStyle">#style/App_EditTextStyle</item>
</style>
#Luksprog answer is correct but not working for me. After some experimentation, I found out that removing the android namespace from editTextStyle made it work for me.
<style name="App_Theme" parent="#android:style/Theme.Holo">
<item name="editTextStyle">#style/App_EditTextStyle</item>
</style>
and make your custom style to extend Widget.EditText or if using the AppCompat theme Widget.AppCompat.EditText:
<style name="App_EditTextStyle" parent="#android:style/Widget.EditText">
<item name="android:background">#drawable/filled_roundededges_box_dark</item>
<item name="android:textColor">#808080</item>
<item name="android:layout_height">45dip</item>
</style>
First, define the style for your EditText. Make sure that the parent style is android:Widget.EditText
<style name="CustomEditTextStyle" parent="android:Widget.EditText">
<item name="android:textColor">#0F0F0F</item>
<!-- ... More items here if needed ... -->
</style>
After that, override the attribute android:editTextStyle in your custom theme. Be aware, if you are using the support library, you will also need to override the attribute editTextStyle (without the android namespace).
<style name="App_Theme" parent="...">
<item name="android:editTextStyle">#style/CustomEditTextStyle</item>
<item name="editTextStyle">#style/CustomEditTextStyle</item> <!-- For compatibility with the support library -->
</style>
If you just need to set a few simple parameters, like text color, the Android namespace has a few parameters that will do that without the need to declare a separate style for the edit text. Eg
<style name="MyStyle" parent="android:Theme.Material.NoActionBar">
<item name="colorPrimary">#color/black</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/white</item>
<item name="android:textColor">#color/black</item>
<item name="android:editTextColor">#color/black</item>
<item name="android:editTextBackground">#color/black</item>
....
</style>
<style name="App_Theme" parent="#android:style/Theme.Holo">
<item name="android:editTextBackground">#drawable/filled_roundededges_box_dark</item>
</style>

Want to overload Button style

I want to overload how an android Button looks, except I want to overload only one attribute i.e. the android:background. I know I could write something like:
<style name="App_TextButtonStyle" parent="???">
<item name="android:background">#drawable/filled_roundededges_nostroke</item>
</style>
Where parent="???" specifies which style I inherit from. My question is which style should I inherit from do that I get everything from the android default style for buttons and just define a new background.
I have used style for buttons without specifying "parent" attribute
<style name="BigButtonStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center_horizontal</item>
<item name="android:background">#drawable/backbutton</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:textSize">8pt</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_margin">10pt</item>
</style>
I think it could be enough for you to define your style without "parent".
This is mostly for future visitors, I found a solution to the problem:
<style name="App_TextButtonStyle" parent="#android:style/Widget.Button">
<item name="android:background">#drawable/filled_roundededges_nostroke</item>
</style>
#android:style/Widget.Button references the default style of the button in the currently selected theme. You could also use the holo widget button style #android:style/Widget.Holo.Button (available since api 11).
You might want to look in <android-sdk-install-folder>/platforms/android-XX/data/res/values for the files styles.xml and themes.xml to check out all styles android uses for a given platform version.

Categories

Resources