android - programacion - Los atributos con el mismo nombre en attrs.xml para la vista personalizada
manual de programacion android pdf (5)
Como respondió Priya Singhal, Android Studio requiere que los nombres de atributos comunes se definan dentro de su propio nombre de estilo. Ya no pueden estar en la raíz.
Sin embargo, hay algunas otras cosas para tener en cuenta (y por eso también estoy agregando una respuesta):
- Los estilos comunes no necesitan ser nombrados de la misma manera que una vista. (Gracias a esta respuesta por señalar eso).
- No necesita usar herencia con un padre.
Ejemplo
Esto es lo que hice en un proyecto reciente que tiene dos vistas personalizadas que comparten los mismos atributos. Siempre y cuando las vistas personalizadas aún tengan los nombres para los atributos y no incluyan un format
, aún puedo acceder a ellas como normales desde el código.
<?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>
Ejemplo optimizado
De hecho, ni siquiera necesito poner los atributos bajo un nombre personalizado. Mientras los defina (les dé un format
) para al menos una vista personalizada, los puedo usar en cualquier lugar (sin el format
). Entonces esto también funciona (y se ve más limpio):
<?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>
Para un proyecto grande, sin embargo, esto podría ser complicado y definirlos en la parte superior en una sola ubicación podría ser mejor (como se recomienda here ).
Estoy escribiendo algunas vistas personalizadas que comparten algunos atributos del mismo nombre. En su respectiva sección <declare-styleable>
en attrs.xml
me gustaría utilizar los mismos nombres para los 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>
Me myattr1
un error que dice que myattr1
y myattr2
ya están definidos. Descubrí que debería omitir el atributo de format
para myattr1
y myattr2
en MyView2
, pero si lo hago, MyView2
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 lograr esto, tal vez algún tipo de espacio de nombres (solo adivinar)?
En caso de que alguien todavía se haya quedado con este problema después de haber intentado la solución disponible. Me quedé con agregar atributo de subtitle
con formato de string
.
Mi solución es eliminar el formato.
antes de:
<attr name="subtitle" format="string"/>
después:
<attr name="subtitle"/>
Estoy publicando esta respuesta ya que la solución publicada anteriormente no funcionó para mí en el estudio de Android. Necesito compartir mis atributos personalizados entre mis vistas personalizadas, así que probé la solución anterior en el estudio de Android pero no tuve suerte. Entonces experimento y hago una manera de hacerlo. Espero 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. Necesitamos hacer que un Padre sea estilo y luego tenemos que heredar ese estilo de padres. Por ejemplo, como he hecho anteriormente: nombre padre de estilo MyView y heredó esto a mi otro styleable como MyView1 y MyView2 respectivamente.
Gracias Lewis, tuve el mismo problema, y tu solución de herencia me dio la pista para hacerlo como a continuación y funciona bien. Acabo de declarar los atributos comunes en los párrafos anteriores y reescribirlos en el cuerpo de la declaración de estilo nuevamente sin formatear. Espero que esto ayude a alguien
<?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>
Solución: simplemente extraiga los atributos comunes de ambas vistas y agréguelas directamente como secundarios 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>