API 级别 21 之前的默认样式资源
Default Style Resource pre API Level 21
我想创建一个自定义 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);
左边是我得到的,右边是我想要的样子:
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
。
如果这看起来很老套,您始终可以从 XML 指定 style="@style/MyImageButtonStyle"
属性的地方扩展您的自定义视图层次结构或单个小部件。
我想创建一个自定义 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);
左边是我得到的,右边是我想要的样子:
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
。
如果这看起来很老套,您始终可以从 XML 指定 style="@style/MyImageButtonStyle"
属性的地方扩展您的自定义视图层次结构或单个小部件。