Sim, há uma maneira:
Suponha que você tenha uma declaração de atributos para seu widget (in attrs.xml
):
<declare-styleable name="CustomImageButton">
<attr name="customAttr" format="string"/>
</declare-styleable>
Declare um atributo que você usará como referência de estilo (in attrs.xml
):
<declare-styleable name="CustomTheme">
<attr name="customImageButtonStyle" format="reference"/>
</declare-styleable>
Declare um conjunto de valores de atributo padrão para o widget (in styles.xml
):
<style name="Widget.ImageButton.Custom" parent="android:style/Widget.ImageButton">
<item name="customAttr">some value</item>
</style>
Declare um tema personalizado (in themes.xml
):
<style name="Theme.Custom" parent="@android:style/Theme">
<item name="customImageButtonStyle">@style/Widget.ImageButton.Custom</item>
</style>
Use este atributo como o terceiro argumento no construtor de seu widget (in CustomImageButton.java
):
public class CustomImageButton extends ImageButton {
private String customAttr;
public CustomImageButton( Context context ) {
this( context, null );
}
public CustomImageButton( Context context, AttributeSet attrs ) {
this( context, attrs, R.attr.customImageButtonStyle );
}
public CustomImageButton( Context context, AttributeSet attrs,
int defStyle ) {
super( context, attrs, defStyle );
final TypedArray array = context.obtainStyledAttributes( attrs,
R.styleable.CustomImageButton, defStyle,
R.style.Widget_ImageButton_Custom );
this.customAttr =
array.getString( R.styleable.CustomImageButton_customAttr, "" );
array.recycle();
}
}
Agora você deve aplicar Theme.Custom
a todas as atividades que usa CustomImageButton
(em AndroidManifest.xml):
<activity android:name=".MyActivity" android:theme="@style/Theme.Custom"/>
Isso é tudo. Agora CustomImageButton
tenta carregar os valores de customImageButtonStyle
atributo padrão do atributo do tema atual. Se nenhum atributo for encontrado no tema ou no valor do atributo, @null
o argumento final obtainStyledAttributes
será usado: Widget.ImageButton.Custom
neste caso.
Você pode alterar os nomes de todas as instâncias e todos os arquivos (exceto AndroidManifest.xml
), mas seria melhor usar a convenção de nomenclatura do Android.
customImageButtonStyle
nesta resposta). É assim que a barra de ação é personalizada no Android. E se você quer dizer mudar um tema em tempo de execução, então não é possível com esta abordagem.name="CustomTheme"
nodeclare-styleable
atributo invólucro servir a qualquer propósito? É apenas para organização, porque não vejo isso sendo usado em lugar nenhum. Posso colocar todos os meus atributos de estilo para vários widgets em um invólucro?Outro aspecto além da excelente resposta de Michael é substituir os atributos personalizados nos temas. Suponha que você tenha várias visualizações personalizadas, todas referindo-se ao atributo personalizado "custom_background".
<declare-styleable name="MyCustomStylables"> <attr name="custom_background" format="color"/> </declare-styleable>
Em um tema você define qual é o valor
<style name="MyColorfulTheme" parent="AppTheme"> <item name="custom_background">#ff0000</item> </style>
ou
<style name="MyBoringTheme" parent="AppTheme"> <item name="custom_background">#ffffff</item> </style>
Você pode se referir ao atributo em um estilo
<style name="MyDefaultLabelStyle" parent="AppTheme"> <item name="android:background">?background_label</item> </style>
Observe o ponto de interrogação, também usado para o atributo android de referência como em
?android:attr/colorBackground
Como a maioria de vocês notou, você pode - e provavelmente deve - usar referências @color em vez de cores codificadas.
Então porque não apenas fazer
<item name="android:background">@color/my_background_color</item>
Você não pode alterar a definição de "my_background_color" em tempo de execução, mas pode facilmente alternar os temas.
fonte