web-dev-qa-db-fra.com

Attributs personnalisés dans styles.xml

J'ai créé un widget personnalisé et je le déclare dans layout.xml. J'ai également ajouté des attributs personnalisés dans attr.xml. Cependant, quand on essaie de déclarer ces attributs dans un style dans styles.xml, cela me donne No resource found that matches the given name: attr 'custom:attribute'.

J'ai mis le xmlns:custom="http://schemas.Android.com/apk/res/com.my.package" dans toutes les balises de styles.xml, y compris <?xml>, <resources>, et <style>, mais cela me donne toujours la même erreur, à savoir qu’il ne trouve pas mon espace de noms XML personnalisé.

Cependant, je peux utiliser mon espace de noms pour attribuer manuellement des attributs à la vue dans mon fichier layout.xml. Il n'y a donc aucun problème avec l'espace de noms. Mon problème est de rendre styles.xml conscient de mon attr.xml.

173
styler1972

Je l'ai compris! La réponse est ET NON spécifiez l'espace de noms dans le style.

<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <style name="CustomStyle">
        <item name="Android:layout_width">wrap_content</item>
        <item name="Android:layout_height">wrap_content</item>

        <item name="custom_attr">value</item> <!-- tee hee -->
    </style>
</resources>
354
styler1972

la réponse ci-dessus est travaillée pour moi, j’ai essayé un changement minime, je déclare stylable pour un élément de classe en ressources.

<declare-styleable name="VerticalView">
    <attr name="textSize" format="dimension" />
    <attr name="textColor" format="color" />
    <attr name="textBold" format="boolean" />
</declare-styleable>

dans declare-styleable, l'attribut name faisait référence à un nom de classe. J'avais donc un appel de classe d'affichage "com.my.package.name.VerticalView", il représentait cette déclaration doit être utilisé dans VerticalView ou dans des sous-classes de VerticalView. afin que nous puissions déclarer un style comme ceci:

<resources>
    <style name="verticalViewStyle">
        <item name="Android:layout_width">match_parent</item>
        <item name="Android:layout_height">36dip</item>

        <item name="textSize">28sp</item>  <!-- not namespace prefix -->
        <item name="textColor">#ff666666</item>
        <item name="textBold">true</item>
    </style>
</resources>

c'est pourquoi nous n'avons pas déclaré d'espace de noms dans l'élément resources, cela fonctionne toujours.

40
VinceStyling

La modification de Styler et Vince a fonctionné pour moi. Je voulais souligner que l'explication de @ vince n'est peut-être pas tout à fait exacte.

Pour tester l'hypothèse que l'attribut name du declare-styleable correspondant au nom de la classe de vue personnalisée nous permettant d'accéder à l'attribut personnalisé sans espace de nom, j'ai changé le nom de la declare-styleable _ (la vue personnalisée s'appelait TestViewFont:

<declare-styleable name="TextViewFont2">
    <attr name="font" format="integer"/>
</declare-styleable>

J'ai ensuite changé l'appel obtainStyledAttributes dans la vue personnalisée pour refléter ceci:

TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TextViewFont2, 0, 0);

Le code a toujours couru. Donc, je ne pense pas que ce soit une sorte d’introspection de la part de la declare-styleable de la classe dont il porte le nom.

Ainsi, je suis amené à croire que tout attribut personnalisé peut être utilisé pour déclarer un style sans faire référence à un espace de noms.

Quoi qu'il en soit, merci pour toute l'aide, les gars, cela a résolu mon problème.

8
Abid H. Mujtaba

values ​​/ styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="defaultButtonColor">@color/red</item>
    <item name="defaultButtonHeight">@dimen/dp_100</item>
</style>

valeurs/attrs.xml

<resources>
    <attr name="defaultButtonColor" format="reference" />
    <attr name="defaultButtonHeight" format="reference"/>
</resources>

values ​​/ colors.xml

<resources>
    <color name="red">#f00</color>
</resources>

values ​​/ dimens.xml

<resources>
    <dimen name="dp_100">100dp</dimen>
</resources>

Utiliser

<Button
    Android:layout_width="wrap_content"
    Android:layout_height="?attr/defaultButtonHeight"
    Android:text="Button"
    Android:textColor="?attr/defaultButtonColor"
    />

enter image description here

DÉMO

5
Phan Van Linh

Au cas où cela aiderait quelqu'un d'autre, mon erreur a été que ma classe d'affichage personnalisée appelait AttributeSet.getAttributeValue p. Ex.

String fontName = attrs.getAttributeValue("http://schemas.Android.com/apk/res-auto", "customFont");

... ce qui a pour conséquence que mon attribut personnalisé n'a pas été lu pour ma vue personnalisée.

Le correctif consistait à utiliser obtainStyledAttributes dans ma vue personnalisée:

 TypedArray styleAttrs = context.obtainStyledAttributes(attrs, R.styleable.MyTextViewStyleable);
 String fontName = styleAttrs.getString(R.styleable.MyTextViewStyleable_customFont);

Un indice que cela fonctionne correctement est que vous pouvez Ctrl/Apple + cliquer sur le R.styleable.MyTextViewStyleable_customFont pour accéder directement à votre définition attrs.xml.

Il m'a fallu un certain temps pour repérer cette différence critique entre mon code et les autres exemples, l'attribut personnalisé fonctionnant correctement lorsqu'il était transmis directement via le format XML (au lieu d'un style).

1
Dan J
  • Définir des attributs

<declare-styleable name="refreshPullRefreshLayout">
        <attr name="refreshColors" format="reference"/>
        <attr name="refreshColor" format="reference"/>
</declare-styleable>
  • Utilisez-le dans un fichier de mise en page comme

<com.aolphn.PullRefreshLayout
     app:refreshColor="@color/main_green"
     app:refreshColors="@array/refresh_color"/>
  • Enfin l'utiliser dans un fichier de style

    La différence entre le fichier de style et le fichier de présentation est que nous n’ajoutons pas prefiex app:
<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

Essayez, passez une belle journée, cela fonctionne pour moi.

0
Aolphn