我希望创建一个在库中使用的自定义ViewGroup
;其中包含一些ImageButton
个对象。我希望每个ImageButton
能够应用一种风格;但除了将属性资源应用于defStyleAttr
参数之外,我无法弄清楚如何以编程方式应用样式;像这样:
mImageButton = new ImageButton(
getContext(), // context
null, // attrs
R.attr.customImageButtonStyle); // defStyleAttr
这个问题是,改变每个ImageButton
样式的唯一方法是在父主题中对该属性应用样式。但我希望能够设置默认样式,而无需为使用此库的每个项目手动设置此属性。
有一个参数完全符合我的要求; defStyleRes
,可以这样使用:
mImageButton = new ImageButton(
getContext(), // context
null, // attrs
R.attr.customImageButtonStyle, // defStyleAttr
R.style.customImageButtonStyle); // defStyleRes
此参数仅在API级别21及更高版本中可用,但我的项目目标是API级别16及更高级别。那么如何在不访问此参数的情况下设置defStyleRes
或应用默认样式?
我根据@EugenPechanec的建议使用ContextThemeWrapper
来应用我的风格,这似乎运作良好,但每个ImageButton
现在都有默认的ImageButton
背景,即使我的风格适用<item name="android:background">@null</item>
。
这是我正在使用的风格:
<style name="Widget.Custom.Icon" parent="android:Widget">
<item name="android:background">@null</item>
<item name="android:minWidth">56dp</item>
<item name="android:minHeight">48dp</item>
<item name="android:tint">@color/selector_light</item>
</style>
这就是我应用它的方式:
ContextThemeWrapper wrapper = new ContextThemeWrapper(getContext(), R.style.Widget_Custom_Icon);
mImageButton = new AppCompatImageButton(wrapper);
左边是我得到的,右边是我想要的样子:
答案 0 :(得分:1)
defStyleAttr
用于从主题属性中解析默认小部件样式。
示例:AppCompatCheckBox
要求R.attr.checkBoxStyle
。您的主题定义了<item name="checkBoxStyle">@style/Widget.AppCompat.CheckBox</item>
。
如果您的主题中未定义该属性,则小部件将拾取其defStyleRes
,例如R.style.Widget_AppCompat_CheckBox
。
请注意,这些不是窗口小部件使用的实际值。
我还没有看到在框架之外使用的defStyleRes
构造函数参数。但是,在向TypedArray
询问资源时,会使用所有这些参数(加上默认值)。
所以四个参数构造函数并不适用于所有平台。您需要找到一种以默认样式提供的方式。考虑一下您想要应用的风格:
<style name="MyImageButtonStyle" parent=""> ... </style>
您需要一种方法将其转换为defStyleAttr
参数。在主题叠加上定义默认样式:
<style name="MyImageButtonThemeOverlay" parent="">
<!-- AppCompat widgets don't use the android: prefix. -->
<item name="imageButtonStyle">@style/MyImageButtonStyle</item>
</style>
现在,您可以使用此主题叠加层创建ImageButton
:
// When creating manually you have to include the AppCompat prefix.
mImageButton = new AppCompatImageButton(
new ContextThemeWrapper(getContext(), R.style.MyImageButtonThemeOverlay)
);
您无需指定任何其他参数,因为AppCompatImageButton
默认会提取R.attr.imageButtonStyle
。
如果看起来很糟糕,您可以随时从指定style="@style/MyImageButtonStyle"
属性的XML中扩充自定义视图层次结构或单个窗口小部件。