web-dev-qa-db-fra.com

Attributs de même nom dans attrs.xml pour une vue personnalisée

J'écris quelques vues personnalisées qui partagent certains attributs du même nom. Dans leur <declare-styleable> section dans attrs.xml J'aimerais utiliser les mêmes noms pour les attributs:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyView1">
        <attr name="myattr1" format="string" />
        <attr name="myattr2" format="dimension" />
        ...
    </declare-styleable>

    <declare-styleable name="MyView2">
        <attr name="myattr1" format="string" />
        <attr name="myattr2" format="dimension" />
        ...
    </declare-styleable>
</resources>

Je reçois une erreur indiquant que myattr1 et myattr2 sont déjà définis. J'ai trouvé que je devais omettre l'attribut format pour myattr1 et myattr2 dans MyView2, mais si je le fais, j'obtiens l'erreur suivante dans la console:

[2010-12-13 23:53:11 - MyProject] ERROR: In <declare-styleable> MyView2, unable to find attribute 

Y a-t-il un moyen pour moi d'accomplir cela, peut-être une sorte d'espacement de noms (juste deviner)?

157
Venator85

Solution: Il suffit d'extraire les attributs communs des deux vues et de les ajouter directement en tant qu'enfants du <resources> noeud:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="myattr1" format="string" />
    <attr name="myattr2" format="dimension" />

    <declare-styleable name="MyView1">
        <attr name="myattr1" />
        <attr name="myattr2" />
        ...
    </declare-styleable>

    <declare-styleable name="MyView2">
        <attr name="myattr1" />
        <attr name="myattr2" />
        ...
    </declare-styleable>
</resources>
351
Venator85

Je poste cette réponse car la solution publiée ci-dessus n'a pas fonctionné pour moi dans Android Studio. Je dois partager mes attributs personnalisés entre mes vues personnalisées, j'ai donc essayé la solution ci-dessus dans = Android Studio mais n'a pas eu de chance. Alors j'expérimente et je vais dans un sens. J'espère que cela pourrait aider quelqu'un à la recherche du même problème.

  <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <!-- parent styleable -->
     <declare-styleable name="MyView">
         <attr name="myattr1" format="string" />
         <attr name="myattr2" format="dimension" />
     </declare-styleable>

     <!-- inheriting parent styleable -->
     <!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
    <declare-styleable name="MyView1" parent="MyView">
        <attr name="myattr1" />
        <attr name="myattr2" />
        <attr name="myBackgroundColor" format="color"/>
    </declare-styleable>


    <!-- inheriting parent styleable -->
    <!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
    <declare-styleable name="MyView2" parent="MyView">
        <attr name="myattr1" />
        <attr name="myattr2" />
        <attr name="myfont" format="string"/>
        ...
    </declare-styleable>
</resources>

Cela fonctionne complètement pour moi. Nous devons rendre un parent stylable, puis nous devons hériter de ce parent stylable. Par exemple, comme je l'ai fait ci-dessus: Nom styleable parent MyView et hérité de celui-ci à mes autres stylables comme MyView1 et MyView2 respectivement.

41
Priya Singhal

Comme Priya Singhal a répondu, Android Studio nécessite que les noms d'attributs communs soient définis dans leur propre nom de style. Ils ne peuvent plus être à la racine.

Cependant, il y a quelques autres choses à noter (c'est pourquoi j'ajoute également une réponse):

  • Les styles courants n'ont pas besoin d'être nommés de la même manière qu'une vue. (Merci à cette réponse pour l'avoir signalé.)
  • Vous n'avez pas besoin d'utiliser l'héritage avec un parent.

Exemple

Voici ce que j'ai fait dans un projet récent qui a deux vues personnalisées qui partagent les mêmes attributs. Tant que les vues personnalisées ont toujours les noms des attributs et n'incluent pas de format, je peux toujours y accéder normalement à partir du code.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- common attributes to all custom text based views -->

    <declare-styleable name="TextAttributes">
        <attr name="text" format="string"/>
        <attr name="textSize" format="dimension"/>
        <attr name="textColor" format="color"/>
        <attr name="gravity">
            <flag name="top" value="48" />
            <flag name="center" value="17" />
            <flag name="bottom" value="80" />
        </attr>
    </declare-styleable>

    <!-- custom text views -->

    <declare-styleable name="View1">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

    <declare-styleable name="View2">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

</resources>

Exemple simplifié

En fait, je n'ai même pas besoin de mettre les attributs sous un nom personnalisé. Tant que je les définis (leur donne un format) pour au moins une vue personnalisée, je peux les utiliser n'importe où (sans le format). Donc cela fonctionne aussi (et semble plus propre):

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="View1">
        <attr name="text" format="string"/>
        <attr name="textSize" format="dimension"/>
        <attr name="textColor" format="color"/>
        <attr name="gravity">
            <flag name="top" value="48" />
            <flag name="center" value="17" />
            <flag name="bottom" value="80" />
        </attr>
    </declare-styleable>

    <declare-styleable name="View2">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

</resources>

Pour un grand projet, cependant, cela pourrait devenir compliqué et les définir en haut dans un seul emplacement pourrait être mieux (comme recommandé ici ).

24
Suragch

Merci Lewis, j'ai eu le même problème, et votre solution d'héritage m'a donné l'astuce pour le faire comme ci-dessous et cela fonctionne bien.Je viens de déclarer des attributs communs à ce qui précède et de le réécrire dans le corps de la déclaration de style sans mise en forme. J'espère que ça aide quelqu'un

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes -->
     <attr name="myattr1" format="string" />
     <attr name="myattr2" format="dimension" />

 <!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" >
    <attr name="myattr1" />
    <attr name="myattr2" />
    <attr name="myBackgroundColor" format="color"/>
</declare-styleable>

<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
    <attr name="myattr1" />
    <attr name="myattr2" />
    <attr name="myfont" format="string"/>
    ...
</declare-styleable>
7
Hanieh Variani

Juste au cas où quelqu'un resterait avec ce problème après avoir essayé la solution disponible. Je suis resté avec l'attribut add subtitle au format string.

Ma solution est de supprimer le format.

avant:

<attr name="subtitle" format="string"/>

après:

<attr name="subtitle"/>

1
Ahmad Muzakki