0

我期待创建一个自定义ViewGroup用于图书馆;其中包含几个ImageButton对象。我希望能够应用每种款式ImageButton;但我不知道如何通过编程方式应用样式,而不是通过将属性资源应用于参数defStyleAttr;像这样:默认样式资源预API级别21

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或应用默认样式,而无需访问此参数?


我使用ContextThemeWrapper应用我的风格,由@EugenPechanec,这似乎运作良好的建议,但每个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); 

左边是什么,我得到,而右边的是什么我想它看起来像:

enter image description hereenter image description here

回答

1

defStyleAttr用于解决来自主题属性的默认小部件样式。

例如:AppCompatCheckBox要求R.attr.checkBoxStyle。您的主题定义为<item name="checkBoxStyle">@style/Widget.AppCompat.CheckBox</item>

如果该属性未在您的主题中定义,则该小部件将从其defStyleResR.style.Widget_AppCompat_CheckBox

请注意,这些不是widget使用的实际值。

我还没有看到defStyleRes构造函数参数在框架之外使用。当询问TypedArray的资源时,所有这些参数(加上默认值)都会被使用。

如何真正解决你的问题

所以在这四个参数的构造函数是不是适用于所有平台。您需要找到一种方法来提供默认样式。考虑你想要的样式应用:

<style name="MyImageButtonStyle" parent=""> ... </style> 

您需要一种方法将其转换为一个defStyleAttr参数。定义一个主题覆盖的默认样式:

// When creating manually you have to include the AppCompat prefix. 
mImageButton = new AppCompatImageButton(
    new ContextThemeWrapper(getContext(), R.style.MyImageButtonThemeOverlay) 
); 

你并不需要指定任何其他参数AppCompatImageButton意志皮卡:

<style name="MyImageButtonThemeOverlay" parent=""> 
    <!-- AppCompat widgets don't use the android: prefix. --> 
    <item name="imageButtonStyle">@style/MyImageButtonStyle</item> 
</style> 

现在你可以使用这个主题覆盖创建ImageButton默认为R.attr.imageButtonStyle


如果看起来哈克在您指定的style="@style/MyImageButtonStyle"属性你可以随时充气您的自定义视图层次或个人从部件XML。

+0

'ContextThemeWrapper'似乎是正确的选择。我以前遇到过,但它完全逃脱了我的想法。不幸的是它造成了另一个问题;由于某些原因,它在每个ImageButton上添加一个背景资源。我可以通过设置'mImageButton.setBackgroundResource(0)'来移除背景,但是我不能在我的样式资源中使用' @ null'这样做,尽管我可以改变其他的属性。任何想法可能会导致这一点? – Bryan

+0

@Bryan好吧,发布在问题结尾处发生了变化的内容,我会研究它。 –

+0

更新了我的新代码和图片。 – Bryan