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
Related
I'm trying to learn how to Style my application using the styles.xml file and I need some clarification on a few things to understand it.
In an Item, what is the difference between setting android:actionbarstyle and just actionbarstyle ? I know that in this particular case, I have to define both, but why? And what about all other cases, for example android:colorPrimary and just colorPrimary? In that case I get an error saying that android:colorPrimary can only be used with min API level 21. So does someone have a good explanation on what the android: prefix does and how it affects my app?
Is there a reference to the different parent styles, such as parent="#style/Widget.AppCompat.Light.ActionBar and what they mean? How do I find a list of the different parent styles available for a specific item and what I can "override" in them? Right now, it's mostly guessing on my part....
Just as a reference, I'm posting my current styles.xml file.
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="MyTheme"/>
<style name="MyTheme" parent="Theme.AppCompat.Light">
<item name="actionBarTheme">#style/MyTheme.ActionBarTheme</item>
<item name="android:actionBarStyle">#style/MyTheme.ActionBarStyle</item>
<item name="actionBarStyle">#style/MyTheme.ActionBarStyle</item>
<item name="colorPrimary">#color/my_green</item>
<item name="colorPrimaryDark">#color/my_forest</item>
<item name="colorAccent">#color/my_soil</item>
<item name="drawerArrowStyle">#style/MyTheme.DrawerArrowStyle</item>
<item name="android:actionOverflowButtonStyle">#style/MyTheme.OverFlow</item>
<item name="android:actionMenuTextColor">#color/white</item>
<item name="homeAsUpIndicator">#drawable/abc_ic_ab_back_mtrl_am_alpha</item>
<item name="android:homeAsUpIndicator">#drawable/abc_ic_ab_back_mtrl_am_alpha</item>
<item name="colorControlNormal">#color/my_green</item>
<item name="colorControlActivated">#color/my_forest</item>
<item name="colorControlHighlight">#color/my_deep_green</item>
</style>
<style name="MyTheme.ActionBarTheme" parent="#style/ThemeOverlay.AppCompat.ActionBar">
<!-- This sets the BACK arrow to white. Otherwise it's black. Must be placed in the theme-->
<item name="colorControlNormal">#color/white</item>
</style>
<style name="MyTheme.ActionBarStyle" parent="#style/Widget.AppCompat.Light.ActionBar">
<item name="android:background">#color/my_green</item>
<item name="background">#color/my_green</item>
<item name="android:titleTextStyle">#style/MyTheme.ActionBar.TitleTextStyle</item>
<item name="titleTextStyle">#style/MyTheme.ActionBar.TitleTextStyle</item>
<item name="colorControlNormal">#color/white</item>
</style>
<style name="MyTheme.ActionBar.TitleTextStyle" parent="#android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">#color/white</item>
</style>
<style name="MyTheme.DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#color/white</item>
</style>
<style name="MyTheme.OverFlow" parent="Widget.AppCompat.ActionButton.Overflow">
<item name="android:tint">#color/white</item>
</style>
</resources>
I will try my best to explain and will concentrate on:
<item name="colorPrimary">#color/my_green</item>
<item name="colorPrimaryDark">#color/my_forest</item>
<item name="colorAccent">#color/my_soil</item>
These attributes are regularly available with API level 21. In general you use attributes with the "android" prefix.
If you define all your styles in the styles.xml of your values folder and if you are using app compat, then you need both.
Without the prefix the attributes applies for pre L devices. i.e. App Compat. To get it work for L devices and higher you need to specifiy the attribute again with the "android" prefix.
And to get the other Android styles you can step into them, like you step into classes and the implementations. For Mac I press the command button and then click with the mouse on the specific style.
I want put the progressBarStyleHorizontal attribute in a style sheet.
I have tried something this, but it didn't work.
<style name="BarraProgreso">
<item name="android:progressDrawable">#android:style/Widget.ProgressBar.Horizontal</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:padding">7dp</item>
<item name="android:indeterminate">true</item>
</style>
Do you know how could use this attribute within a style sheet?
Thanks in advance.
Well, nitzanj was right the problem is the style. Maybe this is what you want:
<style name="BarraProgreso" parent="#android:style/Widget.Holo.Light.ProgressBar.Horizontal">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:padding">7dp</item>
<item name="android:indeterminate">true</item>
</style>
Where using the Holo.Light theme gives the following result:
And this is how you can use your new created style :
<ProgressBar
android:id="#+id/yourIDProgressBar"
style="#style/BarraProgreso" />
Hope this helps :)
The easiest solution would be to make your custom progress bar style extend the required style like so:
<style name="BarraProgreso" parent="#android:style/Widget.ProgressBar.Horizontal">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:padding">7dp</item>
<item name="android:indeterminate">true</item>
</style>
Note that reason what you tried doesn't work is because you're trying to assign a style value into a drawable, which is impossible. By extending the original style you get all it's attributes while still being able to override any attribute, in case the parent style isn't 100% what you need.
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
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.
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