ViewDataBinding getVariable?

Las 2 preguntas principales son:

  • ¿Por qué ViewDataBinding no tiene un método como getVariable("variableName") que buscará una variable y la devolverá o null si no existe ninguna variable con este nombre.
  • ¿Es su forma / solución para lograr este tipo de comportamiento?

Así que para ser más explícito: si no sé el tipo de mi ViewDataBinding , es su manera de obtener su variable o debo saber su tipo?


Aquí es cómo funciona realmente:

  1. Tengo un diseño llamado my_layout.xml :
 <layout> <data> <variable android:name="myVaribale" android:type="String"/> </variable> </data> <RelativeLayout android:id="@+id/root_view" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:text="@{myVariable}"/> </RelativeLayout> <layout> 
  1. Inflar una instancia de su ViewDataBinding :

     MyLayoutBinding binding = (MyLayoutBinding) DataBindingUtil.inflate(inflater, R.layout.my_layout, root, false); 

  2. Puedo obtener su variable llamando al método apropiado:

     String myVariable = binding.getMyVariable(); 

Así que esta fue la forma de obtener una variable cuando sabemos el tipo de ViewDataBinding .


Mi problema está aquí:

Imaginemos que tengo 3 diseños llamados my_layout_1 , my_layout_2 , my_layout_3 y esos 3 diseños están rodeados por una etiqueta <layout> . Esos 3 diseños también tienen la misma variable ( myVariable ).

Así que aquí están los diseños:

My_layout_1

 <layout> <data> <variable android:name="myVariable" android:type="String"/> </variable> </data> <RelativeLayout android:id="@+id/root_view" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:text="@{myVariable}" style="@style/my_style_1"/> </RelativeLayout> <layout> 

My_layout_2

 <layout> <data> <variable android:name="myVariable" android:type="String"/> </variable> </data> <RelativeLayout android:id="@+id/root_view" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:text="@{myVariable}" style="@style/my_style_2"/> </RelativeLayout> <layout> 

My_layout_3

 <layout> <data> <variable android:name="myVariable" android:type="String"/> </variable> </data> <RelativeLayout android:id="@+id/root_view" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:text="@{myVariable}" style="@style/my_style_3"/> </RelativeLayout> <layout> 

Así que el diseño diferente representa un texto con un estilo diferente (sé que se puede lograr por otros, pero el objetivo es explicar por qué necesito esta función getVariable(variableName) .

Imagine ahora que tengo un diseño llamado my_text_container que aleatoriamente contendrá uno de los 3 diseños.

My_text_container

 <layout> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"/> <layout> 

Así que voy a añadir un texto haciendo algo como esto (de nuevo, es sólo para fines de demostración):

 MyTextContainerBinding textContainerBinding = (MyTextContainerBinding) DataBindingUtil.inflate(inflater, R.layout.my_text_container, root, false); int textLayoutRes; int randomNumber = generateNumberBetween0and2(); switch(randomNumber) { case 0: textLayoutRes = R.layout.my_layout_1; break; case 1: textLayoutRes = R.layout.my_layout_2; break; case 2: textLayoutRes = R.layout.my_layout_3; break; } textContainerBinding.getRoot().addView(DataBindingUtil.inflate(inflater, textLayoutRes, root, false)); 

Y finalmente quiero recuperar myVariable pero no sé si es un layout 1, 2 o 3. Básicamente lo que podría hacerse ahora es usar el operador instanceof para comprobar si es un tipo MyLayoutBinding1 , MyLayoutBinding2 o MylayoutBinding3 . Pero como he dicho este caso de uso es sólo para fines de demostración y podría tener 999 diseños diferentes.

Así que lo que me gustaría hacer es:

 ViewDataBinding myLayout = DataBindingUtil.getBinding(textContainerBinding.getRoot().getChildAt(0)); String myVariable = myLayout.getVariable("myVariable"); if(myVariable != null) Log.d(TAG, "myLayout was MylayoutBinding1 or myLayoutBinding2 or myLayoutBinding3"); else Log.d(TAG, "mylayout was not one of the 3 layouts"); 

Lo siento por este (muy) largo post pero gracias por leerlo y por cualquier respuesta futura!

No estoy seguro si lo consigo pero lo que hago es declaro una variable en el diseño como esto:

 <data> <variable name="variableName" type="bla.bla.VariableType"/> </data> 

Entonces primero usted consigue su vinculación de la disposición en onCreate:

 binding = DataBindingUtil.inflate(inflater, R.layout.your_layout, container, false); 

A continuación, debe enviar una variable al diseño en código como:

 binding.setVariableName(yourVariable); 

Entonces usted puede recuperarlo como:

 binding.getVariableName(); 
  1. ¿Por qué ViewDataBinding no tiene getMethodVariable?

    Considere el escenario normal sin vinculante. Tiene un diseño de contenedor de texto. Cómo va a incluir otro diseño dentro de él en una actividad normal.

My_text_container.xml: (Actividad normal)

Inflar esta disposición a su archivo de java usando R.layout.my_text_container, usted no inflará cada disposición a una visión diferente para tener acceso a textview dentro de él. Sólo uno inflar y ir con él.

Así que el mismo procedimiento se sigue en DataBinding, así, cuando se utiliza include tag, los campos respectivos estarán dentro de MyTextContainerLayoutBinding. Usted no tiene que inflarlo una y otra vez con el nombre de la actividad como MyLayout1Binding, MyLayout2Binding. Es por eso que el nombre de la variable se vuelve innecesario aquí.

Creo que la adición de variabilidad a Binding, será más útil en un lugar donde sólo desea mostrar los datos. Los datos de un modelo a través de varios diseños incluidos, más útil con ListViews, Recyclerviews (donde el diseño utiliza los datos de los modelos).

No puede proporcionar un tipo diferente para diseños diferentes, si va a incluir un diseño a otro. (Recuerde que esto enlaza ambos diseño a nombre único (parent_activity en su contenedor de casos)).

P.ej:

UserProfileModel:

 public class UserProfileModel { String firstname; String lastname; public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } 

}

My_layout_1.xml;

 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="user" type="com.hourglass.lingaraj.bindingusingvariables.UserProfileModel" /> </data> <LinearLayout android:orientation="vertical" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:visibility="visible" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.firstname}" style="@style/mystyle_1"/> <include layout ="@layout/my_layout_2" app:user="@{user}" /> </LinearLayout> </layout> 

My_layout_2.xml:

 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.hourglass.lingaraj.bindingusingvariables.UserProfileModel"/> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:visibility="visible" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.lastname}" style="@style/mystyle_2"/> </RelativeLayout> </layout> 

MainActivity.java:

 public class MainActivity extends AppCompatActivity { MyLayout1Binding layout_binding; UserProfileModel data_model; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_layout_1); data_model = new UserProfileModel(); data_model.setFirstname("Lingaraj"); data_model.setLastname("Sankaravelu"); layout_binding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.my_layout_1,null,false); layout_binding = DataBindingUtil.setContentView(this,R.layout.my_layout_1); layout_binding.setUser(data_model); } } 

Como se ve, estamos utilizando sólo un modelo para rellenar datos a través del diseño incluido. Así que no hay necesidad de obtener el nombre de la variable para verificar qué modelo se carga como está enlazado a un solo diseño.

  1. No hay ninguna solución para lograr esto, nosotros de lo he intentado.

Así que mi respuesta será No, no se puede obtener un nombre de variable de vinculante

Referencias.

No More findViewById

Vinculación de datos de Android: esa cosa

Vinculación de datos de Android: agregando cierta variabilidad

Vinculación de datos de Android: Express Yourself

  • Android databinding error de prueba de unidad Error al analizar las opciones del compilador de enlace de datos. Params:
  • Cómo configurar Android DataBinding en diseños anidados
  • Cómo correctamente 2-way-bind numérico a Android editText
  • Android databinding usando operador lógico "&&"
  • Android: Databinding, notifyPropertyChanged () no funciona?
  • Error al importar el tipo de lista en un archivo xml mediante la vinculación de datos de Android
  • Actualización de la interfaz de usuario mediante la biblioteca de enlace de datos
  • Cómo realizar vinculación de datos de dos vías con un ToggleButton?
  • Adaptador de enlace de Android que pasa varios argumentos causa error
  • android: error de enlace de datos: no se puede encontrar clase de símbolo
  • Enlace de datos bidireccional en EditText
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.