Why are some of my styles not working with lower APIs? - android

I have a quick question!
In my styles.xml file, I have
<style name="TextViewStyle" parent="android:Widget.TextView">
<item name="android:padding">20px</item>
<item name="android:background">#9cd0e8</item>
<item name="android:textColor">#254b7c</item>
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
</style>
And in my activity_main.xml, I have
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:theme="#+styles/TextViewStyle"
android:text="Sample Text"/>
What I am trying to do is, in my Android application, on a certain activity I plan to place many TextViews with similar properties. Instead of writing these 'properties' every time with each TextView instance, I grouped them together in a style in styles.xml file and set theme of each of my TextViews to that style.
It works fine and does what I want it to do, but only with APIs above 21! My application's supposed to support devices from API level 15 up. Why is my approach not working with lower APIs?
Please help soon. I need to finish this soon.
EDIT
By 'working', I meant that the attributes I set in my style (padding, color, etc.) appear on the TextViews as they should. In lower APIs however, the TextViews appear as if I had not applied any attribute on them. Plain text appears instead of a styled one.

remove parent from your style
remove android:theme from textView, (why there is + sign?)
instead of theme put this into your textView
style="#style/TextViewStyle"
btw, use dp instead of px ;)

Related

Androidx AppCompatButton looks different from Button even on high API Level device

According to the documentation
A Button which supports compatible features on older versions of the
platform, including:
Allows dynamic tint of its background via the background tint methods
in ViewCompat. Allows setting of the background tint using
R.attr.backgroundTint and R.attr.backgroundTintMode. This will
automatically be used when you use Button in your layouts and the
top-level activity / dialog is provided by appcompat. You should only
need to manually use this class when writing custom views.
Now, this makes me assume that the following two buttons would look exactly the same on high level devices.
<androidx.appcompat.widget.AppCompatButton
android:text="AppCompatButton"
android:id="#+id/appcompatbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_below="#id/appcompatbutton"
android:id="#+id/button"
android:layout_width="wrap_content"
android:text="Button"
android:layout_height="wrap_content" />
However, here is how it actually looks:
I ran this on the following emulator:
Galaxy Nexus, API:28 (720 x 1280 xhdpi)
And when I apply buttonStyle in my appTheme like this:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="buttonStyle">#style/Widget.MaterialComponents.Button</item>
</style>
It changes the AppCompatButton but not the normal button like this:
(Note the slight difference in the rounded edges)
I also tried to create a custom button that both inherited from android.widget.Button and also androidx.appcompat.widget.AppCompatButton, both of these buttons show the same behaviour as using AppCompatButton in xml does. So it feels like the only outlier is Button in XML.
Question 1:
This all seems incredibly confusing according to me. Can someone clarify this as either a bug or feature?
EDIT 1
Doing debugging I found that the Button actually gets transformed into a MaterialButton, see the following:
Question 2:
Why is this transformation happening?
EDIT 2
Question 2 answer:
The transformation of Button to MaterialButton is due to the parent theme I was using.
Question 3:
How do you implement a custom button which works just like Button in xml would?
As a side note and personal opinion, also a slight repetition, this system is not only confusing but its hard to get it right and foolproof for future changes. In addition to this, the documentation is very poor. I would appreciate if an answer to this would be included as well, or at least a discussion regarding it, how to deal with it for example.
Short answers.
This all seems incredibly confusing according to me. Can someone clarify this as either a bug or feature?
They use different styles.
Why is this transformation happening?
There is an auto-inflation enabled which will replace <Button with <com.google.android.material.button.MaterialButton at runtime.
How do you implement a custom button which works just like Button in xml would?
You can customize the attributes in xml or the theme attributes.
Long answers.
They use different styles.
The default style of MaterialButton is Widget.MaterialComponents.Button.
This style inherits from Widget.AppCompat.Button but changes some attributes.
Here you can find the differences.
The main difference is here:
<item name="shapeAppearance">?attr/shapeAppearanceSmallComponent</item>
You can read more about shaping in the official doc.
If you navigate through the style you will find:
<style name="ShapeAppearance.MaterialComponents.SmallComponent">
<item name="cornerSize">#dimen/mtrl_shape_corner_size_small_component</item>
</style>
where mtrl_shape_corner_size_small_component = 4dp.
It explains the slight difference in the rounded edges.
Also you are using
<item name="buttonStyle">#style/Widget.MaterialComponents.Button</item>.
It doesn't work for the MaterialButton. You have to use:
<item name="materialButtonStyle">#style/Widget.MaterialComponents.Button</item>
The auto-inflation is here.
The MaterialComponentsViewInflater replaces some framework widgets with Material Components ones at inflation time, provided a Material Components theme is in use.
Something similar happens also with AppCompat (you can check that MaterialComponentsViewInflater extends AppCompatViewInflater).
It means that, the <Button is replaced <com.google.android.material.button.MaterialButton at runtime, if you are using a Material Theme.
There are different options. One of these is to define a custom style for buttons.
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
...
<item name="materialButtonStyle">#style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="cornerRadius">xxx</item>
</style>
or
<style name="MyButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="shapeAppearanceOverlay">#style/SShapeAppearanceOverlay.MyApp.Button.Rounded</item>
</style>
<style name="ShapeAppearanceOverlay.MyApp.Button.Rounded" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">xxdp</item>
</style>
I changed the <Button> to <ImageButton>
Quick and short way.
Don't forget to check & change references in java/kotlin files. Compiler will alert you any way.

How to professionally organise the styling of buttons? (SDK 26+, min SDK 21)

What is best practice to organise styling of buttons of a professional android application? Assume a larger contemporary application (SDK 26+, min SDK 21).
This question is answerable, as both the sources of Material Design and the setup of Android Studio give enough clues and examples of the patterns of the intended professional usage. Surely the user is not limited to this patterns, but following them, makes the application play well together with the sources of Material Design and provides best maintainability.
I find several ingredients related to the styling of buttons.
#style/Widget.AppCompat.Button
#style/Widget.AppCompat.Button.Colored
#style/TextAppearance.AppCompat.Button
#style/TextAppearance.AppCompat.Widget.Button
#color/foreground_material_dark
?colorAccent
?textColorPrimary
?android:colorForeground
?textAppearanceButton
There may be more.
How are all the ingredients related?
How are they intended to be used together in professional theming?
You can look up the sources. However, even knowing all details does not give the full picture of the intended usage. This question is asking to draw the picture.
(Min SDK 21)
General Approach
Granularity
I think it an enough fine-grained approach to separate the text appearance from the backgrounds. This gives the option to combine different backgrounds with different text appearances. It also matches the two style settings provided by Button and the organisation of Material Design. Hence it addresses the question, how it is intended to be used.
The price is, that each Button needs both settings:
Button text: android:textAppearance
Button background: style
To even lower this price styles_material.xml in fact takes an advanced approach. Each button style already includes a default text appearance. So in the normal case I only have to apply the button style.
<Button
style="?defaultButtonStyle"
I follow this pattern for my own button styling, as the question is for the intended usage. If I want to modify the default, I add an alternative text appearance by setting it to android:textAppearance.
<Button
style="?defaultButtonStyle"
android:textAppearance="?smallButtonTextAppearance"
For very special buttons I still can adjust the styling on the level of the layout file. This is the lowest level of granularity.
Hint: Be aware that android:textAppearance has a very low
precedence. If you set a text attribute somewhere in the theme (or style),
you will overwrite the same attribute in all of android:textAppearance.
It works with a similar force like the "!important" annotation in CSS,
which can be a pretty pitfall.
Flexible theming
Without
If I don't plan to use different themes, I can set the styles directly into the layouts.
<Button
style="#style/My.DefaultButtonStyle"
android:textAppearance="#style/My.SmallButtonTextAppearance"
...
With
If a want to be able to exchange themes, I map all types of styles to attributes first. Then I set the styles indirectly by using the attributes. This gives me the option to connect other styles for other themes, without the need to duplicate layouts.
<Button
style="?defaultButtonStyle"
android:textAppearance="?smallButtonTextAppearance"
...
I personally prefer not to use or mix given attributes, but to fully define my own set of attributes addressing my design. So the levels of the onion stay cleanly separated.
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<!-- button text appearance -->
<attr name="defaultButtonTextAppearance" format="reference" />
<attr name="smallButtonTextAppearance" format="reference" />
<!-- button backgrounds -->
<attr name="defaultButtonStyle" format="reference" />
<attr name="alarmButtonStyle" format="reference" />
In the themes the attributes are mapped to theme specific styles.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="OtherTheme" parent="Theme.AppCompat">
<!-- button text appearance -->
<item name="defaultButtonTextAppearance">#style/OtherTheme.DefaultButtonTextAppearance</item>
...
<!-- button backgrounds -->
<item name="defaultButtonStyle">#style/OtherTheme.DefaultButtonStyle</item>
...
Button Text
If I track down the styles to the sources I come to a file data/res/values/styles_material.xml, which defines the root of all button text appearances. TextAppearance.Material.Button inherits from TextAppearance.Material, but the four relevant attributes for buttons are overwritten.
<style name="TextAppearance.Material">
<item name="textColor">?attr/textColorPrimary</item>
<item name="textColorHint">?attr/textColorHint</item>
<item name="textColorHighlight">?attr/textColorHighlight</item>
<item name="textColorLink">?attr/textColorLink</item>
<item name="textSize">#dimen/text_size_body_1_material</item>
<item name="fontFamily">#string/font_family_body_1_material</item>
<item name="lineSpacingMultiplier">#dimen/text_line_spacing_multiplier_material</item>
</style>
<style name="TextAppearance.Material.Button">
<item name="textSize">#dimen/text_size_button_material</item>
<item name="fontFamily">#string/font_family_button_material</item>
<item name="textAllCaps">true</item>
<item name="textColor">?attr/textColorPrimary</item>
</style>
It can be overwritten by my own inherited styles. It also shows, that it would be easy to write my own text appearance style without using inheritance at all.
Color
Understanding Androids text color management system is them most confusing part, because the system is quite powerful. Here comes some enlightenment.
In the above TextAppearance.Material.Button I find text color is specified by the attribute ?textColorPrimary. This attribute again is based on the attribute ?android:colorForeground.
The attribute ?android:colorForeground is the central switch to set the text colors. Be default all text colors are calculated based on this setting, also those of the buttons. For example different grades of greyed-out or opaque variants are calculated for disabled buttons, for body text, etc.
Instead of touching dozens of different places it is a good idea to set the common default text color here and rely on the default Android color calculating system as far as useful. Tweak it in details.
<item name="android:colorForeground">#color/orange_700</item>
This setting defaults to #color/foreground_material_dark.
Hint 1: If you edit the setting by use of
the Android Studio Theme Editor, it will possibly change the
value of#color/foreground_material_dark. To me it does not
feel like a good idea to change a value of material dark because
it is not my realm. Better use a reference like shown before.
Hint 2: The Theme Editor is an appropriate tool to discover
the relations of the color attributes system. This relations reveal,
when you experimentally try to edit the different attributes with the editor.
If I want a button text color that varies from the overall text color, I set it on the level of the text appearance style.
Hint 3: Using ?android:colorForeground does not work out of the
box below API 26. For a workaround see here.
Text size
The text size is the factor of the text appearance, that I typically want to directly adjust to my own design within my customised text appearance styles.
<style name="My.SmallButtonTextAppearance" parent="My.DefaultButtonTextAppearance">
<item name="android:textSize">16sp</item>
</style>
TextAppearance.Material.Button takes the text size default from the resource #dimen/text_size_button_material. There is no system with a central text size setting comparable to the text color setting system.
All caps
The root style TextAppearance.Material.Button set's all caps to true. There is not even a resource, the value is taken from. It's just hard coded.
<item name="textAllCaps">true</item>
There is a high chance, I want to set it to false in my customised button styles.
<item name="android:textAllCaps">false</item>
Font family
As with the text colors the font family typically is a system with a common central nature. How is it managed for the buttons? The root style TextAppearance.Material.Button makes use a the string resource #string/font_family_button_material.
<item name="fontFamily">#string/font_family_button_material</item>
In the file data/res/values/donttranslate_material.xml this is set to sans-serif-medium, while in the file data/res/values-watch/donttranslate_material.xml is is set to sans-serif-condensed.
<string name="font_family_button_material">sans-serif-medium</string>
<string name="font_family_button_material">sans-serif-condensed</string>
This sans-serif settings are mapped to my chosen font family within the fonts setup. Typically sans-serif is fine for button text. For further customisation of the fonts I point to this question.
Button Style
Apart from using a color for the background, a xml resource file can be applied to specify the background with fancy corners, color gradients or other graphical effects, also supporting different backgrounds for different states of the button.
This part is strongly influenced by my design. I will typically use my own background.
On the other hand there is a rich system of predefined button backgrounds resource files in material design. I would like to give a short overview here, but that's beyond my skills and seems so large to be worth a topic of it's own.
The style for the background should not contain settings for width, height or margins, as this belongs into the surrounding layout. On the other hand the padding belongs into the background style.
Button styles of Material Design
In the file data/res/values/styles_material.xml I find nine button styles I may inherit from. If I write my very own, a should not forget to set a default text appearance.
The root element is Widget.Material.Button. It set's the default text appearance to ?textAppearanceButton. Hence, setting this attribute is an option to directly use the material design button styles without inheritance and yet have your customised default text appearance.
<!-- Bordered ink button -->
<style name="Widget.Material.Button">
<item name="background">#drawable/btn_default_material</item>
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="minHeight">48dip</item>
<item name="minWidth">88dip</item>
<item name="stateListAnimator">#anim/button_state_list_anim_material</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
The attribute ?colorAccent is used, to set the color of Widget.AppCompat.Button.Colored. See the Android Studio Theme Editor. See #drawable/btn_colored_material.
Note that the default text appearance of Widget.AppCompat.Button.Colored varies and is not set by a customisable attribute.
<!-- Colored bordered ink button -->
<style name="Widget.Material.Button.Colored">
<item name="background">#drawable/btn_colored_material</item>
<item name="textAppearance">#style/TextAppearance.Material.Widget.Button.Colored</item>
</style>
<!-- Small bordered ink button -->
<style name="Widget.Material.Button.Small">
<item name="minHeight">48dip</item>
<item name="minWidth">48dip</item>
</style>
<!-- Borderless ink button -->
<style name="Widget.Material.Button.Borderless">
<item name="background">#drawable/btn_borderless_material</item>
<item name="stateListAnimator">#null</item>
</style>
Note that the default text appearance of Widget.Material.Button.Borderless.Colored varies and is not set by a customisable attribute.
<!-- Colored borderless ink button -->
<style name="Widget.Material.Button.Borderless.Colored">
<item name="textAppearance">#style/TextAppearance.Material.Widget.Button.Borderless.Colored</item>
</style>
Note that Widget.Material.Button.ButtonBar.AlertDialog inherits from Widget.Material.Button.Borderless.Colored. Same limitations of the default text appearance apply.
<!-- Alert dialog button bar button -->
<style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored">
<item name="minWidth">64dp</item>
<item name="minHeight">#dimen/alert_dialog_button_bar_height</item>
</style>
<!-- Small borderless ink button -->
<style name="Widget.Material.Button.Borderless.Small">
<item name="minHeight">48dip</item>
<item name="minWidth">48dip</item>
</style>
<style name="Widget.Material.Button.Inset">
<item name="background">#drawable/button_inset</item>
</style>
<style name="Widget.Material.Button.Toggle">
<item name="background">#drawable/btn_toggle_material</item>
<item name="textOn">#string/capital_on</item>
<item name="textOff">#string/capital_off</item>
</style>
Personally I would either use one of this predefined button styles or inherit my own from Widget.Material.Button. This keeps the hierarchy of inheritance low and the code easily readable. It saves me at most three lines of code if I inherit from another style, while the code becomes less maintainable.
There are exceptions to this rule of thumb. For example #drawable/btn_borderless_material is private. So I either have to inherit from Widget.Material.Button.Colored or create a copy of the file.
Appendix
Related questions
Attributes
Defining custom attrs
Android Use custom themes to modify style attributes
Android "?colorPrimary" vs "?attr/colorPrimary"?
Inheritance issue, when using property androidTextapperance vs. property style
Colors
Setting a color based on theme
Attribute android:colorForeground not working in API 23
android themes - defining colours in custom themes
Fonts
How to set default font family for entire Android app
How to change fontFamily of TextView in Android
What is the difference between fontFamily and typeFace in android?
it's up to you and depends on your application.. also you can set a background using an xml file
eg:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<solid android:color="#8c0000" />
</shape>
</item>
<item >
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<solid android:color="#c62f2c" />
</shape>
</item>
</selector>

Issues changing the color of views

So I am trying to change my app color to blue and some of most the views I have are not willing to cooperate with me.
Here is the image:
Here I want to change the color of the green parts on the spinner, edittext and checkbox views (which are green) to black or blue.
I've looked all over Stack Overflow and I can't find the solution!
Thank you very much, If possible I would like to have a XML solution but I wouldn't mind a programmatic solution!
Add these to your base theme in styles.xml
<item name="colorControlNormal">#color/YOUR_COLOR</item>
<item name="colorControlActivated">#color/YOUR_COLOR</item>
<item name="colorControlHighlight">#color/YOUR_COLOR</item>
Note: The above change will affect the EditTexts and other views probably throughout the application.
If not, and if you are using the AppCompat v22 support library, you can specify the theme in the EditText like: android:theme="#style/Theme.App.Base.
This will ensure the style won't also affect other views in your layouts that you don't want to change
Also if you want to change the above solution, just add another Theme specific to EditTexts and Spinners and apply it to all Spinners if you want
<style name="MyWidgetTheme">
<item name="colorControlNormal">#color/YOUR_COLOR</item>
<item name="colorControlActivated">#color/YOUR_COLOR</item>
<item name="colorControlHighlight">#color/YOUR_COLOR</item>
</style>
and in your EditText, Spinner or any other View, just assign this theme:
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Demo"
android:lines="1"
android:theme="#style/MyWidgetTheme"
/>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/MyWidgetTheme"></Spinner>
Take a look to this resource generator.
Choose your color, the widgets you want to generate and voila! You copy them to your project and reference them in your xmls.

Themes in android

A create a simple Theme as
<style name='one'>
<item name='android:textColor'>#eea</item>
<item name='android:textSize'>20sp</item>
</style>
However on viewing in the emulator the screen goes black.when i do not apply theme the screen has a white background .
what really happens here.i am just starting with android.
In addition ,if a apply a theme to my activity then the attributes of the theme applies to all components of my activity say button,textfields and edittexts .
why would i then write
android:textSize=?android:textSize
to reference value from the theme for any button in my layout when the same value would already be applying.
is the syntax above the correct way to reference an attribute from my theme to assign to attribute for any view in my layout.
thanks
tejinder
Yeah, so you need to do a little more reading.
Let's start with the basics,
You need to understand the differente betweent an Attribute, a Style, and a Theme.
An Attribute is something that can be styled. For instance: android:textSize is an attribute that can have any value.
A Style is a set of specific attributes that will be applied to a Widget. They are defined
in your /values/styles.xml
For instance:
<style name="normalTextThin" parent="android:Widget.Holo.Light.TextView">
<item name="android:gravity">left|center_vertical</item>
<item name="android:padding">8dp</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:textSize">16sp</item>
</style>
The styles can be applied either as part of a theme or directly as theme-independent.
Theme-indepentent styling of a widget is like this:
<TextView
android:id="#+id/text"
style="#style/normalTextThin"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
You are then theming only that one TextView.
A Theme is a collection of Styles that can be applied to a part of your UI, such a a whole Activity, or your whole Application.
For instance:
<style name="AppTheme" parent="android:Theme.Light">
<item name="android:editTextStyle">#style/EditTextAppTheme</item>
<item name="android:buttonStyle">#style/ButtonAppTheme</item>
<item name="android:imageButtonStyle">#style/ImageButtonAppTheme</item>
</style>
Here, we are declaring that all EditText in your application will use the style named EditTextAppTheme, and so forth and on. When done like this, in order to actually have the theme be active, you declare it in the manifest:
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
That means that you are not required to declare the style on each widget you create.
<EditText
android:id="#+id/input"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="#string/hint_search">
<requestFocus />
</EditText>
That widget right there would already be styled using EditTextAppTheme without the need of you explicitely declaring so.
I recommend you try to read on what attributes can be styled, how to style them, and so forth and on.
If you don't want to though, it's fine, you can still get a lot done with the following tools for styling:
ActionBarStyleGenerator to help you create styles for the ActionBar.
Android Holo Colors to help you style standard widgets.
Hope that helps.
Additional Info
Let me clarify on the whole ?attr/attributeName
The ? means that the system will choose the specific attributeName value for the current Configuration (not specific to different themes). This should be used only when you want the value to be different on different configurations. For example:
?android:attr/actionBarSize
This line is a dimension, and it will be different not based on the current theme, but on the current device screen size and orientation (values, values-land, values-sw600dp).
It's important to know that specifying ?android: means you are accessing preset Android values, not yours. If you have or want to create and use your own attribute values for specific configurations, you must do the following:
Create a file named attrs.xml on your /values/ folder.
Declare the desired custom attribute:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<attr name="my_custom_attr" format="reference" />
</resources>
Declare a value for the custom attribute, let's say on your own theme.
<style name="AppTheme" parent="android:Theme.Light">
<item name="my_custom_attr">#resource_type/resource_name</item>
<item name="android:editTextStyle">#style/EditTextAppTheme</item>
<item name="android:buttonStyle">#style/ButtonAppTheme</item>
<item name="android:imageButtonStyle">#style/ImageButtonAppTheme</item>
</style>
And then you can use it on the Widget you'd like:
Hope that clears things out.
EDIT 2
For a better answer to your question, please update your question. And like I said, read more on how to properly create styles.
The Theme named 'one', what do you want to apply it to? An activity, a Widget, the whole Application?
How are you applying the theme? Show the lines of code where you specify the usage of theme 'one'.
Your theme as you specified is simply not a properly constructed theme/style.
<style name='one'>
<item name='android:textColor'>#eea</item>
<item name='android:textSize'>20sp</item>
</style>
This says absolutely nothing, and it is definitely not suitable for an Activity-level theme. The reason you specify a parent is so your theme can inherit all of the attributes from the parent, and then you specifiy which ones to change.
For instance, if you want to use your theme and have a light background, do this:
<style name='one' parent="android:Theme.Holo.Light>
<item name='android:textColor'>#eea</item>
<item name='android:textSize'>20sp</item>
</style>
But even here, despite the fact that it will apply, you don't want to have the same text color and size for the whole application do you? That'd be nonsense, different text color and sizes account for a big part of the user experience, so rather than setting those values from what we can refer to as the main style, we can create substyles and apply them to certain widgets.
I can't really go any more detailed that what I already have, the above explains how to accomplish Widget-specific styling, and activity/application level theming.
For a complete start-up guide, read the Android Developer Site, try the test styles declared there, see how they work, and until then try to create your own, don't try to create something out of nowhere if no reading has been made.

How does an android:attr style work?

I'm trying to build an Android UI via layouts. I start with the following:
<TextView
android:id="#+id/..."
android:layout_marginTop="8dip"
android:text="..."
style="?android:attr/listSeparatorTextViewStyle"/>
And that looks good (all caps, smaller font, dividing bar underneath it). Now I want to extend the style, so I change it to the following:
<TextView
android:id="#+id/..."
android:layout_marginTop="8dip"
android:text="..."
style="#style/section_title"/>
With a style of:
<style name="section_title" parent="#android:attr/listSeparatorTextViewStyle">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
</style>
And that doesn't work (font is correct, but the divider line is gone).
How come... that?
When you're using:
style="?android:attr/listSeparatorTextViewStyle"
you're using the style pointed by this attribute(listSeparatorTextViewStyle). If you look in the platform themes.xml you'll see that the style that is actually used for this attribute is Widget.TextView.ListSeparator.White. So this is the style you should extend in your custom style.
Unfortunately that style is private and you can't extend it, or you shouldn't extend it(for reference, see this bug report from google). Your best option would be to copy that entire style, Widget.TextView.ListSeparator.White(Widget.TextView.ListSeparator isn't public as well so would have to also copy that), in your custom style and use that instead of extending the style from the android platform(see this response from the link above).

Categories

Resources