Question

J'ai écrit un widget personnalisé pour un contrôle que nous utilisons largement dans notre application. La dérive de la classe widget de ImageButton et il étend dans quelques moyens simples. J'ai défini un style que je peux appliquer au widget comme il est utilisé, mais je préfère le mettre en place à travers un thème. En R.styleable je vois les attributs de style comme widget imageButtonStyle et textViewStyle. Est-il possible de créer quelque chose comme ce widget pour l'usage que j'ai écrit?

Était-ce utile?

La solution

Oui, il y a une façon:

Supposons que vous avez une déclaration d'attributs pour votre widget (en attrs.xml):

<declare-styleable name="CustomImageButton">
    <attr name="customAttr" format="string"/>
</declare-styleable>

Déclarer un attribut que vous utiliserez pour une référence de style (en attrs.xml):

<declare-styleable name="CustomTheme">
    <attr name="customImageButtonStyle" format="reference"/>
</declare-styleable>

déclarer un ensemble de valeurs d'attributs par défaut pour le widget (en styles.xml):

<style name="Widget.ImageButton.Custom" parent="android:style/Widget.ImageButton">
    <item name="customAttr">some value</item>
</style>

Déclarer un thème personnalisé (en 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 (en 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 ); // see below
        this.customAttr =
            array.getString( R.styleable.CustomImageButton_customAttr, "" );
        array.recycle();
    }
}

Maintenant, vous devez appliquer Theme.Custom à toutes les activités que l'utilisation CustomImageButton (en AndroidManifest.xml):

<activity android:name=".MyActivity" android:theme="@style/Theme.Custom"/>

C'est tout. Maintenant CustomImageButton tente de charger les valeurs d'attributs par défaut d'attribut customImageButtonStyle du thème actuel. Si aucun tel attribut se trouve dans le thème ou la valeur d'attribut est @null alors l'argument final obtainStyledAttributes sera utilisé. Widget.ImageButton.Custom dans ce cas

Vous pouvez modifier les noms de toutes les instances et tous les fichiers (sauf AndroidManifest.xml), mais il serait préférable d'utiliser Android convention de nommage.

Autres conseils

Un autre aspect en plus d'une excellente réponse de michael est prépondérant attributs personnalisés dans les thèmes. Supposons que vous avez un certain nombre de vues personnalisées que tous se réfèrent à l'attribut personnalisé « de custom_background ».

<declare-styleable name="MyCustomStylables">
    <attr name="custom_background" format="color"/>
</declare-styleable>

Dans un thème que vous définissez ce que la valeur est

<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 vous référer à l'attribut dans un style

<style name="MyDefaultLabelStyle" parent="AppTheme">
    <item name="android:background">?background_label</item>
</style>

Notez le point d'interrogation, comme également utilisé pour référence attribut android comme dans

?android:attr/colorBackground

Comme vous l'avez remarqué, vous pouvez probablement -et références utilisation de doit si @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 modifier la définition de « my_background_color » lors de l'exécution, alors que vous pouvez facilement changer de thème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top