Pregunta

Estoy escribiendo un par de vistas personalizadas que comparten algunos atributos del mismo nombre. En su sección respectiva en <declare-styleable> attrs.xml me gustaría utilizar los mismos nombres de atributos:

<?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>

Recibo un error que indica que myattr1 y myattr2 ya están definidos. Me di cuenta de que debería omitir el atributo format para myattr1 y myattr2 en MyView2, pero si hago eso, obtengo el siguiente error en la consola:

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

¿Hay alguna manera de que pudiera lograr esto, tal vez algún tipo de namespacing (sólo una suposición)?

¿Fue útil?

Solución

Solución: Simplemente extraer atributos comunes de ambos puntos de vista y añadirlos directamente como hijos del nodo <resources>:

<?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>

Otros consejos

He colgado esta respuesta como la solución anterior, publicado no funcionó para mí en Android Studio. Necesito compartir mis atributos personalizados entre mis vistas personalizadas por lo que trató la solución anterior de Android Studio, pero no tuvo suerte. Así que yo experimento y vaya una manera de hacerlo. Esperan que pueda ayudar a alguien que busca el mismo problema.

  <?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>

Esto funciona para mí por completo. Tenemos que hacer una styleable Padres y entonces tenemos que heredar ese styleable padres. Por ejemplo, como lo he hecho anteriormente: El nombre del padre styleable MyView y heredado esta a mi otro styleable como MYVIEW1 y MyView2 respectivamente.

As Priya Singhal answered, Android Studio requires the common attribute names to be defined within their own style name. They can't be at the root any more.

However, there are a couple other things to note (which is why I am also adding an answer):

  • The common styles don't need to be named the same thing as a view. (Thanks to this answer for pointing that out.)
  • You don't need to use inheritance with a parent.

Example

Here is what I did in a recent project that has two custom views that both share the same attributes. As long as the custom views still have the names for the attributes and don't include a format, I can still access them as normal from 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>

Streamlined example

In fact, I don't even need to put the attributes under a custom name. As long as I define them (give them a format) for at least one custom view, I can use them anywhere (without the format). So this also works (and looks cleaner):

<?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>

For a large project, though, this could get messy and defining them at the top in a single location might be better (as recommended here).

Thanks Lewis I had the same problem , and your inheritance solution gave me the hint for doing it like below and it works fine.I just declared common attributes at the above and rewrite it in the body of style declaration again without formatting. I hope it helps someone

<?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>

Just in case someone still stuck with this problem after tried available solution. I stuck with add subtitle attribute with string format.

My solution is remove the format.

before:

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

after:

<attr name="subtitle"/>

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top