Oui, il y a un moyen:
Supposons que vous ayez une déclaration d'attributs pour votre widget (in attrs.xml
):
<declare-styleable name="CustomImageButton">
<attr name="customAttr" format="string"/>
</declare-styleable>
Déclarez un attribut que vous utiliserez pour une référence de style (dans attrs.xml
):
<declare-styleable name="CustomTheme">
<attr name="customImageButtonStyle" format="reference"/>
</declare-styleable>
Déclarez un ensemble de valeurs d'attribut par défaut pour le widget (in styles.xml
):
<style name="Widget.ImageButton.Custom" parent="android:style/Widget.ImageButton">
<item name="customAttr">some value</item>
</style>
Déclarez un thème personnalisé (dans themes.xml
):
<style name="Theme.Custom" parent="@android:style/Theme">
<item name="customImageButtonStyle">@style/Widget.ImageButton.Custom</item>
</style>
Utilisez cet attribut comme troisième argument dans le constructeur de votre 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();
}
}
Vous devez maintenant appliquer Theme.Custom
à toutes les activités qui utilisent CustomImageButton
(dans AndroidManifest.xml):
<activity android:name=".MyActivity" android:theme="@style/Theme.Custom"/>
C'est tout. Essaie maintenant CustomImageButton
de charger les valeurs d' customImageButtonStyle
attribut par défaut à partir de l' attribut du thème actuel. Si aucun attribut de ce type n'est trouvé dans le thème ou la valeur de l'attribut est @null
alors le dernier argument à obtainStyledAttributes
sera utilisé: Widget.ImageButton.Custom
dans ce cas.
Vous pouvez modifier les noms de toutes les instances et de tous les fichiers (sauf AndroidManifest.xml
), mais il serait préférable d'utiliser la convention de dénomination Android.
customImageButtonStyle
dans cette réponse). C'est ainsi que la barre d'action est personnalisée sur Android. Et si vous voulez dire changer un thème à l'exécution, alors ce n'est pas possible avec cette approche.name="CustomTheme"
dans l'declare-styleable
attribut emballage sert à quelque chose ? Est-ce juste pour l'organisation, parce que je ne le vois pas utilisé nulle part. Puis-je simplement mettre tous mes attributs de style pour divers widgets dans un même wrapper?Un autre aspect en plus de l'excellente réponse de Michael est de remplacer les attributs personnalisés dans les thèmes. Supposons que vous ayez un certain nombre de vues personnalisées qui font toutes référence à l'attribut personnalisé "custom_background".
<declare-styleable name="MyCustomStylables"> <attr name="custom_background" format="color"/> </declare-styleable>
Dans un thème, vous définissez la valeur
<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>
Vous pouvez faire référence à l'attribut dans un style
<style name="MyDefaultLabelStyle" parent="AppTheme"> <item name="android:background">?background_label</item> </style>
Notez le point d'interrogation, également utilisé pour l'attribut android de référence comme dans
?android:attr/colorBackground
Comme la plupart d'entre vous l'ont remarqué, vous pouvez - et devriez probablement - utiliser des références @color au lieu de couleurs codées en dur.
Alors pourquoi ne pas simplement faire
<item name="android:background">@color/my_background_color</item>
Vous ne pouvez pas changer la définition de "my_background_color" à l'exécution, alors que vous pouvez facilement changer de thème.
la source