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"&开发者_开发问答gt;@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
精彩评论