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?
- Cómo vincular el diseño con varios calificadores
- Cómo acceder a la vista dentro de un diseño incluido mediante el enlace de datos
- DataBinding con Android Dialog
- Android Data binding, El valor del atributo "android: text" asociado con un tipo de elemento "TextView" no debe contener el carácter '<'
- No se puede hacer referencia a otro ID de vista en vinculación de datos de Android
Aquí es cómo funciona realmente:
- 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>
-
Inflar una instancia de su ViewDataBinding :
MyLayoutBinding binding = (MyLayoutBinding) DataBindingUtil.inflate(inflater, R.layout.my_layout, root, false);
-
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!
- ¿Puedo enlazar un mensaje de error a un TextInputLayout?
- Vinculación de datos android: cómo obtener útiles mensajes de error
- Enlace de datos bidireccional con doble valor en EditText
- Vinculación de datos: establece la propiedad si no es nula
- Dagger 2 en Android, sin mensajes de error
- Ejemplo de enlace de datos de 2 vías de android no funcionan como se describe
- Data Binding Android - El parámetro de tipo T tiene límites superiores incompatibles: ViewDataBinding y MainActivity
- Cómo configurar el error en EditText utilizando DataBinding MVMF de Framwork
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();
-
¿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.
- 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
- Volley vs Aquery vs Android Async HTTP
- Uso de renderscript para procesamiento y mediacodec para codificación