values recorrer enum ejemplos clases clase java android android-layout enums android-databinding

ejemplos - recorrer enum java



¿Cómo establecer el atributo enum por valor en lugar de nombre en el diseño de Android? (2)

No puedo establecer la enumeración por valor sino solo por nombre

Eso no es del todo cierto. No podría establecer el valor con DataBinding ni siquiera por su nombre, lo que sucede es que el valor de un atributo definido en un xml se pasa a la View través del constructor. Una View puede tener tanto un atributo como un definidor, pero ese no es necesariamente el caso. Por ejemplo, si establece un valor para android:text de un TextView , ese valor se establece en com.android.internal.R.styleable.TextView_text que luego se recupera del AttributeSet en el constructor. Si usa DataBinding, se llama a setText() , pero son 2 cosas completamente diferentes, la característica es la misma pero no están relacionadas en el código.

Dado que no puede modificar MyInnerView y que no hay un configurador al que pueda llamar myAttr , su única opción es pasarlo a través del constructor. El enlace de datos simplemente no es factible, incluso con un BinderAdapter no podría establecer el valor en AttributeSet porque la View ya está instanciada en ese punto.

Opción 1 - temas

Definir un nuevo atributo.

<attr name="MyInnerViewAttrValue" format="integer" />

Luego resuelva este atributo con un estilo, por ejemplo, podría tener

<style name="AppTheme.Foo"> <item name="MyInnerViewAttrValue">0</item> </style> <style name="AppTheme.Bar"> <item name="MyInnerViewAttrValue">1</item> </style>

Colócalo en el diseño xml.

<com.example.MyInnerView ... app:myAttr="?attr/MyInnerViewAttrValue" />

Y luego llame a setTheme(int) en la Activity antes de que las vistas sean instanciadas.

Opción 2 - BindingAdapter personalizado

Si quisiera establecer su valor Enlace de datos (porque tenía un configurador o porque quería piratear MyInnerView con reflexión), entonces tendría que crear un BindingAdapter personalizado, por ejemplo.

@BindingAdapter("myAttrValue") public static void setMyAttr(MyInnerView myInnerView, int value) { switch (value) { case 0: myInnerView.foo(); break; default: myInnerView.bar(); } }

Luego en el diseño xml

<com.example.lelloman.dummy.MyInnerView ... myAttrValue="@{model.attr}" />

Y dale el valor int desde tu ViewModel

public class MyInnerViewModel { public int getAttr() { return 1234; } }

Tengo una vista personalizada sosteniendo otra. Jerarquía:

MyOuterView ->MyInnerView

MyInnerView tiene un atributo de enumeración como:

<attr name="myAttr" format="enum"> <enum name="foo" value="0"/> <enum name="bar" value="1"/> </attr>

Entonces puedo instanciar el componente en MyOuterView XML como:

<com.example.MyInnerView .... app:myAttr="foo"/>

Que funciona, por supuesto. El MyOuterView ofrece un argumento para la personalización en sí. Basado en este argumento, quiero establecer el argumento de MyInnerView .

El comportamiento deseado es que puedo trabajar con el enlace de datos como:

<com.example.MyInnerView .... app:myAttr="@{data.getMyAttr()}"/>

donde getMyAttr() ve como:

public int getMyAttr() { return myAttr; // returns 0 or 1 }

El resultado es un problema de compilación.

**** / error de enlace de datos **** msg: no se puede encontrar el configurador para el atributo ''app: myAttr'' con el tipo de parámetro int en com.example.MyInnerView

Así que obviamente no puedo establecer la enumeración por valor sino solo por nombre. ¿Alguna idea además de crear el MyInnerView programáticamente? Tenga en cuenta que no puedo cambiar MyInnerView .


Desafortunadamente, puede usar el nombre del atributo como app:myAttr="@{...}" solo si hay un configurador para eso y este definidor se asigna al nombre del atributo o se puede resolver por su nombre. En su caso, si este atributo se usa solo en el constructor de View y view no tiene ningún método público para cambiar esto, todavía tiene algunas soluciones posibles: extienda View e implemente la lógica para personalizar la vista como lo hace este atributo (si es posible) haz BindingAdapter y usa Reflection (si es posible). - crea tu propia vista copiando y pegando y arreglando)