7

Supongamos que estoy haciendo algunas vistas nuevas con atributos de estilo. Me declararlos thusly (esto es how the documentation says to do it:¿Cuál es el punto de declarar estilo?

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

    <declare-styleable name="TriangleView"> 
     <attr name="direction"> 
      <enum name="NE" value="0" /> 
      <enum name="NW" value="1" /> 
      <enum name="SW" value="2" /> 
      <enum name="SE" value="3" /> 
     </attr> 
    </declare-styleable> 

    <declare-styleable name="BannerView"> 
     <attr name="direction"> 
      <enum name="NE" value="0" /> 
      <enum name="NW" value="1" /> 
      <enum name="SW" value="2" /> 
      <enum name="SE" value="3" /> 
     </attr> 
     <attr name="thickness" format="dimension" /> 
    </declare-styleable> 
</resources> 

Sin embargo, esto no funcionará porque todos los atributos son aparentemente en el mismo espacio de nombres, y me sale el error Error: Attribute "direction" has already been defined

Así que al parecer tengo que mover. los atributos aparentemente duplicados fuera del <declare-styleable> así:

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


    <attr name="direction"> 
     <enum name="NE" value="0" /> 
     <enum name="NW" value="1" /> 
     <enum name="SW" value="2" /> 
     <enum name="SE" value="3" /> 
    </attr> 

    <declare-styleable name="BannerView"> 
     <attr name="thickness" format="dimension" /> 
    </declare-styleable> 
</resources> 

Pero esto plantea dos cuestiones:

  1. Si esto funciona, ¿cuál es exactamente el punto de <declare-styleable>?
  2. ¿Qué sucede si deseo que el atributo se comporte de manera diferente en diferentes vistas? Por ejemplo, si la dirección BannerView solo puede ser up o down.

Respuesta

15

¿Cuál es exactamente el punto de <declare-styleable>?

<declare-stylable> etiquetas le permiten declarar atributos para sus vistas personalizadas que luego puede establecer para esas vistas en xml. En realidad, hay 3 formas de utilizar el atributo:

  1. declarar un <attr> dentro de una etiqueta <declare-stylable>.
  2. Defina un espacio de nombre personalizado en su diseño xml que apunte al nombre del paquete de la aplicación (por ejemplo, app). Use el atributo personalizado en su diseño (por ejemplo, app:direction="NW").
  3. En su vista personalizada, anule los constructores con un parámetro AttributeSet, obtenga un TypedArray y lea los atributos personalizados, si los hubiera, y luego dentro del constructor indique a la vista cómo usar esos atributos de manera apropiada.

¿Qué sucede si deseo que el atributo se comporte de manera diferente en diferentes vistas? Por ejemplo, si la dirección de BannerView solo puede ser hacia arriba o hacia abajo.

intentar algo como esto:

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

    <attr name="direction"> 
     <enum name="NE" value="0" /> 
     <enum name="NW" value="1" /> 
     <enum name="SW" value="2" /> 
     <enum name="SE" value="3" /> 
    </attr> 

    <declare-styleable name="TriangleView"> 
     <attr name="direction" /> 
    </declare-styleable> 

    <declare-styleable name="BannerView"> 
     <attr name="direction" /> 
     <attr name="thickness" format="dimension" /> 
    </declare-styleable> 
</resources> 

Cuando usted construye su diseño xml de TriangleView o BannerView, puede utilizar el ejemplo app:direction="NW" para ambos. En los constructores con AttributeSet en TriangleView o BannerView, los atributos tienen el mismo formato que el original, pero lo que hace con ese valor depende de la implementación de los constructores en cada vista correspondiente (pueden ser los mismos o diferente para ambos).

Si desea atributos que se definen differenly (es decir.diferente "formato" o "enumeración") para diferentes vistas, luego debe crear diferentes atributos con diferentes nombres.

+0

¡Increíble, en realidad me ayudó también para attr definido en la aplicación-compat lib! Entonces, básicamente, si un attr ya está definido, debe usarse en declare-styleable, sin intentar anular el formato. Cool cool cool – Redwarp