Existe muy poca documentación sobre la declare-styleableetiqueta mediante la cual podemos declarar estilos personalizados para componentes. Encontré esta lista de valores válidos para el formatatributo de la attretiqueta. Si bien eso es bueno en la medida de lo posible, no explica cómo usar algunos de esos valores. Navegando attr.xml (la fuente de Android para los atributos estándar), descubrí que puedes hacer cosas como:
<!-- The most prominent text color. -->
<attr name="textColorPrimary" format="reference|color" />
El formatatributo evidentemente se puede ajustar a una combinación de valores. Presumiblemente, el formatatributo ayuda al analizador a interpretar un valor de estilo real. Luego 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:
- ¿Cuál es la diferencia entre un atributo de estilo que puede tomar uno de un conjunto de
enumvalores y uno que puede tomar un conjunto deflagvalores? - ¿Alguien sabe de alguna documentación mejor sobre cómo
declare-styleablefunciona (aparte de la ingeniería inversa del código fuente de Android)?
fuente

enumyflag.La respuesta de @Aleadam es muy útil, pero en mi humilde opinión, omite una diferencia importante entre
enumyflag. El primero está destinado a que 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.xmlahora podemos hacer<com.example.MyWidget myenum="two" myflags="one|two" ... />Entonces, una enumeración selecciona uno de sus valores posibles, mientras que las banderas se pueden combinar. Los valores numéricos deben reflejar esta diferencia, por lo general, querrá que la secuencia vaya
0,1,2,3,...para enumeraciones (para usarse como índices de matriz, por ejemplo) y banderas para1,2,4,8,...que se puedan agregar o eliminar de forma independiente, usando OR bit|a bit para combinar banderas.Podríamos definir explícitamente "metabanderas" con valores que no sean una potencia de 2, y así introducir una especie de abreviatura de combinaciones comunes. Por ejemplo, si hubiéramos incluido esto en nuestra
myflagsdeclaración<flag name="three" value="3" />entonces podríamos haber escrito
myflags="three"en lugar demyflags="one|two", para obtener resultados completamente idénticos a3 == 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 poner todas las banderas a la vez.
Más sutilmente, podría darse el caso de que una bandera esté implícita en otra. Entonces, en nuestro ejemplo, suponga que la
eightbandera que se está configurando debería forzar la configuración de lafourbandera (si no lo estaba ya). A continuación, podríamos volver a definireightpara incluir previamente, por así decirlo, lafourbandera,<flag name="eight" value="12" /> <!-- 12 == 8|4 -->Por último, si declara los atributos en un proyecto de biblioteca pero desea aplicarlos en diseños de otro proyecto (que depende de la biblioteca), deberá usar un prefijo de espacio de nombres 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>fuente