usar una studio que objeto instanciar ejemplo declarar declaraciĆ³n declaracion declara como clases clase android xml styleable declare-styleable

una - Declarar atributos estiloables en Android



que es una declaraciĆ³n en java (2)

Aquí está la pregunta: definir attrs personalizados con algo de información, pero no mucho.

Y esta post . Tiene buena información sobre banderas y enumeraciones:

Banderas de atributos XML personalizados

Los indicadores son tipos de atributos especiales, ya que solo se les permite un subconjunto de valores muy pequeño, es decir, aquellos que se definen debajo de la etiqueta de atributo. Los indicadores se especifican mediante un atributo de "nombre" y un atributo de "valor". Se requiere que los nombres sean únicos dentro de ese tipo de atributo, pero no es necesario que los valores sean. Esta es la razón por la que durante la evolución de la plataforma Android teníamos "fill_parent" y "match_parent", ambos mapeados con el mismo comportamiento. Sus valores fueron idénticos.

El atributo de nombre se correlaciona con el nombre utilizado en el lugar de valor dentro del formato XML y no requiere un prefijo de espacio de nombre. Por lo tanto, para el "tilingMode" de arriba elegí "center" como el valor del atributo. Podría haber elegido tan fácilmente "estirado" o "repetido", pero nada más. Ni siquiera se habría permitido sustituirlo por los valores reales.

El atributo de valor debe ser un entero. La elección de la representación numeral hexadecimal o estándar depende de usted. Hay algunos lugares dentro del código de Android donde ambos se usan y el compilador de Android está feliz de aceptar cualquiera.

Enum de atributos XML personalizados

Los mensajes se usan de manera casi idéntica a los indicadores con una disposición, se pueden usar indistintamente con números enteros. Bajo el capó, los Enume y los Enteros se asignan al mismo tipo de datos, a saber, un Entero. Al aparecer en la definición de atributo con enteros, los enumerados sirven para evitar "números mágicos" que siempre son malos. Esta es la razón por la que puede tener un "android: layout_width" con una dimensión, un entero o una cadena con nombre "fill_parent".

Para poner esto en contexto, supongamos que creo un atributo personalizado llamado "layout_scroll_height" que acepta un entero o una cadena "scroll_to_top". Para hacerlo, agregaría un atributo de formato "entero" y lo seguiría con la enumeración:

<attr name="layout_scroll_height" format="integer"> <enum name="scroll_to_top" value="-1"/> </attr>

La única estipulación al usar Enums de esta manera es que un desarrollador que usa su vista personalizada podría colocar el valor "-1" a propósito en los parámetros de diseño. Esto desencadenaría la lógica de casos especiales de "scroll_to_top". Tal comportamiento inesperado (o esperado) podría relegar rápidamente a su biblioteca a la pila del "código heredado" si los valores de Enum se eligieron mal.

Según lo veo, los valores reales que puede agregar en realidad a un atributo están limitados por lo que puede obtener de él. Consulte la referencia de la clase AttributeSet here para obtener más sugerencias.

Puede obtener:

  • booleanos ( getAttributeBooleanValue ),
  • flotadores ( getAttributeFloatValue ),
  • getAttributeIntValue ( getAttributeIntValue ),
  • getAttributeUnsignedIntValue (como getAttributeUnsignedIntValue ),
  • y cadenas ( getAttributeValue )

Hay muy poca documentación sobre la etiqueta de declare-styleable mediante la cual podemos declarar estilos personalizados para los componentes. Encontré esta lista de valores válidos para el atributo de format de la etiqueta attr . Si bien eso está bien hasta donde llega, no explica cómo usar algunos de esos valores. Al attr.xml (la fuente de Android para los atributos estándar), descubrí que puedes hacer cosas como estas:

<!-- The most prominent text color. --> <attr name="textColorPrimary" format="reference|color" />

El atributo de format se puede establecer evidentemente en una combinación de valores. Presumiblemente, el atributo de format ayuda al analizador a interpretar un valor de estilo real. Entonces descubrí esto en attr.xml:

<!-- Default text typeface. --> <attr name="typeface"> <enum name="normal" value="0" /> <enum name="sans" value="1" /> <enum name="serif" value="2" /> <enum name="monospace" value="3" /> </attr> <!-- Default text typeface style. --> <attr name="textStyle"> <flag name="normal" value="0" /> <flag name="bold" value="1" /> <flag name="italic" value="2" /> </attr>

Ambos parecen declarar un conjunto de valores permitidos para el estilo indicado.

Entonces tengo dos preguntas:

  1. ¿Cuál es la diferencia entre un atributo de estilo que puede tomar uno de un conjunto de valores enum y uno que puede asumir un conjunto de valores de flag ?
  2. ¿Alguien sabe de alguna documentación mejor sobre cómo funciona el declare-styleable (que no sea la ingeniería inversa del código fuente de Android)?

La respuesta de @Aleadam es muy útil, pero a pesar de que omite una gran diferencia entre enum y flag . El primero está diseñado para que nosotros elijamos uno y solo un valor cuando asignamos el atributo correspondiente para alguna Vista. Sin embargo, los valores de este último se pueden combinar utilizando el operador OR bit a bit.

Un ejemplo, en res/values/attr.xml

<!-- declare myenum attribute --> <attr name="myenum"> <enum name="zero" value="0" /> <enum name="one" value="1" /> <enum name="two" value="2" /> <enum name="three" value="3" /> </attr> <!-- declare myflags attribute --> <attr name="myflags"> <flag name="one" value="1" /> <flag name="two" value="2" /> <flag name="four" value="4" /> <flag name="eight" value="8" /> </attr> <!-- declare our custom widget to be styleable by these attributes --> <declare-styleable name="com.example.MyWidget"> <attr name="myenum" /> <attr name="myflags" /> </declare-styleable>

En res/layout/mylayout.xml ahora podemos hacer

<com.example.MyWidget myenum="two" myflags="one|two" ... />

Entonces, un enum selecciona uno de sus valores posibles, mientras que los indicadores se pueden combinar. Los valores numéricos deben reflejar esta diferencia, normalmente querrá que la secuencia sea 0,1,2,3,... para enumeraciones (para usar como índices de matriz, por ejemplo) y banderas para ir 1,2,4,8,... para que puedan agregarse o eliminarse de forma independiente, utilizando OR a nivel de bit para combinar banderas.

Podríamos definir explícitamente "meta banderas" con valores que no son un poder de 2, y así introducir un tipo de combinación de combinaciones comunes. Por ejemplo, si hubiéramos incluido esto en nuestra declaración myflags

<flag name="three" value="3" />

entonces podríamos haber escrito myflags="three" en lugar de myflags="one|two" , para resultados completamente idénticos como 3 == 1|2 .

Personalmente, me gusta incluir siempre

<flag name="none" value="0" /> <!-- or "normal, "regular", and so on --> <flag name="all" value="15" /> <!-- 15 == 1|2|4|8 -->

lo que me permitirá desarmar o configurar todas las banderas a la vez.

Más sutilmente, podría darse el caso de que una bandera esté implícita por otra. Entonces, en nuestro ejemplo, suponga que la bandera eight que se está configurando debe obligar a que se establezca la bandera four (si no estaba ya). Podríamos redefinir eight para preincluir, por así decirlo, la bandera four ,

<flag name="eight" value="12" /> <!-- 12 == 8|4 -->

Finalmente, si declara los atributos en un proyecto de biblioteca pero desea aplicarlos en diseños de otro proyecto (dependiendo de la lib), necesitará usar un prefijo de espacio de nombre que debe vincular en el elemento raíz XML. P.ej,

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:auto="http://schemas.android.com/apk/res-auto" ... > <com.example.MyWidget auto:myenum="two" auto:myflags="one|two" ... /> </RelativeLayout>