What are the key differences between android:theme and style attributes used for views like buttons and textviews in android layout xml files?
How to use them?
and When to use which?
There are two key differences:
First, attributes assigned to a view via style will apply only to that view, while attributes assigned to it via android:theme will apply to that view as well as all of its children. For example, consider this style resource:
<style name="my_background">
<item name="android:background">#drawable/gradient</item>
</style>
If we apply it to a LinearLayout with three child TextViews by using style="#style/my_background", then the linearlayout will draw with a gradient background, but the backgrounds of the textviews will be unchanged.
If instead we apply it to the LinearLayout using android:theme="#style/my_background" then the linearlayout and each of the three textviews will all use the gradient for their background.
The second key difference is that some attributes only affect views if they are defined in that view's theme. For example, consider this style resource:
<style name="checkboxes">
<item name="colorAccent">#caf</item>
<item name="colorControlNormal">#caf</item>
</style>
If I apply this to a CheckBox using style="#style/checkboxes", nothing will happen. If instead I apply it using android:theme="#style/checkboxes", the color of the checkbox will change.
Just like the first rule said, styles containing theme attributes will apply to all children of the view with the android:theme attribute. So I can change the color of all checkboxes in a linearlayout by applying android:theme="#style/checkboxes" to my linearlayout.
Related
I have designed a custom theme for the activity.Everything seems to be applying fine to the views except divider color for listview.(android:dividercolor attribute).
I applied it along with android:dividerheight attribute as suggested in other threads.divider height also applied correctly.
But when i apply divider color through activity xml file for the specific listview,custom color was applied correctly.
Can't we apply custom divider color from custom theme?
Instead of android:dividercolor, use android:listDivider.
<style name="MyAppTheme" parent="Some.Base.Theme">
<item name="android:listDivider">#color/my_divider_color</item>
<item name="android:dividerHeight">4dp</item>
</style>
I am very happy with this website. I'm learning a lot.
Today I doubt has arisen. And I want to put a style to a FrameLayout. and do not use.
The style is as follows:
<style name="textAsk">
<item name="android:textColor">#000000</item>
<item name="android:padding">2dp</item>
<item name="android:minWidth">88dp</item>
<item name="android:minHeight">36dp</item>
<item name="android:textSize" >18dp</item>
<item name="android:layout_marginRight">12dp</item>
<item name="android:layout_marginLeft">12dp</item>
<item name="android:layout_marginTop">5dp</item>
</style>
I show fragments that are changing in a FrameLayout. Each Fragment contains a TextView with a text in it.
There are a lot of fragments, and I would like to set a style, a common one, for all the TextViews, in order to save time and not setup the style in each TextView.
I had tried this code:
<FrameLayout
android:id="#+id/fragmentaskGRP1"
android:layout_width="match_parent"
android:layout_height="450dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
style="#style/textAsk"/>
But the only thing that works for me is:
<item name="android:layout_marginRight">12dp</item>
<item name="android:layout_marginLeft">12dp</item>
<item name="android:layout_marginTop">10dp</item>
Thank you very much for everything
The FrameLayout doesn't support the textColor or textSize attribute (API). So it's never set for the FrameLayout and ignored. See the style properties section from the guide Styles and Themes for more information.
Quote from the Guide:
However, if you apply a style to a View that does not support all of the style properties, the View will apply only those properties that are supported and simply ignore the others.
Define the text-related styles in a separate style definition and use it for this one for the matching views like TextView
The thing is that child views don't inherit styles from their enclosing ViewGroup. Styles can have parents, but in your case TextViews are not going to get these attributes from the FrameLayout.
The other styles will not be applied to fragments. You have to create another logic to apply styles to all fragments (Most probably you will have to apply styles individually to each fragment)
FrameLayout have nothing to do with text so textColor, textSize will have no effect.
Where as minWidth, minHeight are properties of View it think they should work.
My goal is to use Theme.Light in NumberPicker while using a different theme in my application. I generate the NumberPicker at runtime. How do I achieve this? Any suggestions and links are appreciated!
Styles and themes are read from attributes (android:textColor, etc.).
If you are inflating a layout in your view, then you can customize your layout.
If you want to change the style of all NumberPickers, then you just have to customize the style in XML:
Example with button:
<style name="OrangeButton" parent="#style/custom_ButtonStyle">
<item name="android:background">#drawable/button_orange_selector</item>
<item name="android:padding">12dp</item>
</style>
...then you set this control as the default control in your app:
#style/custom_ButtonStyle
Do the same for number picker.
If the goal is to only set a style for one control, once, then you could apply the style in an xml layout you'll create that will only contain the original NumberPicker, and the style="#style/your_style. You'd then need to create an xml layout with a LinearLayout that wrap a NumberPicker that you styled, Inflate it, and then get this view. It sounds like it's not really optimal, though.
I created a few drawables to handle state colors, etc for list view items. These work when I set the android:listSelector property to them on the list definition in the layout. But, I'd like to apply them globally, so in my theme, I declared the style, like:
<style name="QFListView" parent="#android:style/Widget.ListView">
<item name="android:listSelector">#drawable/listview_selector</item>
</style>
Why doesn't this work, or, what should I be doing to get it to work?
Android first draws the ListView background as well as the dividers. Then, the system draws the list selector. Finally, ListView renders all itemviews on top of that. Thanks to this diagram, it is clear the list selector will never be visible with opaque background set to itemviews.
Read this : #Customizing itemviews background
http://cyrilmottier.com/2011/08/08/listview-tips-tricks-3-create-fancy-listviews/
attrs.xml:
<declare-styleable name="AppTheme">
<attr name="actionbarCompatLogoStyle" format="reference" />
</declare-styleable>
styles.xml:
<style name="Theme.MyApp" parent="android:style/Theme.Light">
<item name="actionbarCompatLogoStyle">#style/ActionBarCompatLogo</item>
</style>
<style name="ActionBarCompatLogo">
<item name="android:layout_width">30dp</item><!-- original image is huge -->
<item name="android:layout_height">30dp</item>
<item name="android:src">#drawable/app_logo</item>
</style>
Problem: if I use this, image dimensions won't work (huge image):
ImageButton logo = new ImageButton(context, null, R.attr.actionbarCompatLogoStyle);
If I use this, it works (tiny image, which is what I want):
<ImageView style="#style/ActionBarCompatLogo"></ImageView>
Why?
Any attribute prefixed with layout_ is part of a LayoutParams object. LayoutParams are special arguments to the parent view about how it should lay out the child view. The type of LayoutParams you set on a view is dependent on what type of ViewGroup you are adding it to. Each container view type can be different and so can the LayoutParams. layout_weight is specific to LinearLayout, layout_below is for RelativeLayout, etc. layout_width and layout_height are part of the base ViewGroup LayoutParams.
The takeaway from this is that LayoutParams are not parsed by the view's constructor, they're parsed by another step that your code above isn't doing. (The LayoutInflater involves the parent ViewGroup's generateLayoutParams method.)
Since LayoutParams are dependent on the intended parent of the View it's not recommended to put LayoutParams in styles. It mostly works when you are inflating views from layout XML but it has other implications similar to the edge case you've found here and requires you to be aware of them. For example, a style may specify layout_weight for a LinearLayout but if a view with that style is added to a RelativeLayout instead it will not behave as expected since RelativeLayout does not support layout_weight.
As far as I know it's not possible to apply styles to specific views programmatically, only via XML.
What you can do is to set a theme on your activity inside the onCreate() method. Consult this question: android dynamically change style at runtime