Android DataBinding y MVVM – Utilizar los mismos archivos de diseño para diferentes condiciones utilizando los mismos modelos de vista

He estado desarrollando una aplicación con vinculación de datos y MVVM.

Estoy tratando de usar un diseño alternativo para mi aplicación en modo horizontal. Yo tengo:

layout/fragment_content.xml layout-land/fragment_content.xml 

Ambos diseños tienen las mismas vistas con aspecto diferente, y obtener feeds de los mismos modelos de vista, como esto:

 <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data class="MyBinding"> <variable name="viewModel" type="com.myapp.package.viewModel.VMFirst"/> <variable name="controlModel" type="com.myapp.package.viewModel.VMSecond"/> </data> <DIFFERENT CONTENT HERE> 

Todas las vistas e identificaciones existen en ambos diseños.

Bueno, el problema es que no se compila, el error es simplemente "cannot find symbol method getViewModel" y getter para la otra variable.

Lo que he intentado hasta ahora:

  1. Uso de las carpetas de diseño y distribución (Error, el error se explica más arriba)

  2. Uso de alias de diseño Uso de alias de diseño que encontré aquí Edición 199344: El enlace de datos no funciona con los alias de diseño . No cambié nada en archivos xml mientras intentaba este enfoque. Esto también falló, el error es Could not write to com.myapp.package.databinding.MyBinding se Could not write to com.myapp.package.databinding.MyBinding

¿No es posible utilizar data etiqueta de datos de enlace de data en varios archivos de diseño? ¿Qué debo usar para usar diseños diferentes para diferentes estados mientras uso la vinculación de datos? Gracias !

Editar: eliminar la class="MyBinding" no cambió los errores.

Yo uso mucho MVVM en mis aplicaciones y también estoy construyendo una biblioteca a su alrededor.

Sigo la convención de que hay un solo ViewModel en cada XML. Además, el nombre de la variable viewmodel es el mismo en todos los XML.

Por lo tanto, en su caso, puede crear otra clase ViewModel que contenga VMFirst y VMSecond .

 public class ParentVM { VMFirst first; VMSecond second; } 

Tanto los XML (retrato y paisaje) tendrán los mismos nombres, digamos activity_main.xml .

 <layout> <data> <variable type="ParentViewModel" name="vm"/> </data> 

Entonces no se requiere chequeo en el código MainActivity.

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewDataBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setVariable(BR.vm, new ParentViewModel()); } 

Esto funciona.

Ventajas de un solo ViewModel

De hecho, debido a que sigo el mismo nombre de variable en todos los xmls, puedo incluir la lógica de enlace en una clase base MvvmActivity sí mismo. Por lo tanto, todas mis actividades se ven como:

 public class MainActivity extends MvvmActivity { @NonNull @Override protected ViewModel createViewModel() { return new MainViewModel(); } @Override protected int getLayoutId() { return R.layout.activity_main; } } 

Implementación de MvvmActivity : MvvmActivity.java

Otra ventaja de mantener una variable de enlace de datos constante es que puede configurar los adaptadores RecyclerView o ViewPager en XML. Consulte Configuración de RecyclerView desde XML para obtener más detalles.

De forma predeterminada, se generará una clase Binding basada en el nombre del archivo de diseño, convirtiéndolo en caso Pascal y sufijo "Binding". El archivo de diseño anterior era main_activity.xml, por lo que la clase generate era MainActivityBinding. – Datos de encuadernación

Y se genera en tiempo de compilación.

Por lo que, seleccione el diseño diferente por código java.

 layout/ R.layout.activity_main R.layout.activity_main_tablet values/ <bool name="is_mobile">true</bool> <bool name="is_tablet">false</bool> values-w820dp/ <bool name="is_mobile">false</bool> <bool name="is_tablet">true</bool> @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(getResources().getBoolean(R.bool.is_mobile)) { ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); } else { ActivityMainTabletBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main_tablet); } } 
  • Android Studio instala un APK para cada módulo
  • No se pueden cambiar los módulos buildVariant
  • Error de Gradle "Atributo" xxx "ya se ha definido" en Android Studio
  • ¿"ShouldOverrideUrlLoading" es realmente obsoleto? ¿Qué puedo usar en su lugar?
  • Android Studio Error al recuperar - Conexión rechazada: conectar
  • Android Studio (0.1.6-0.2.13) error de instrucción no jumbo
  • Mejores prácticas para variantes de construcción con sabor con gradle en android studio
  • Error de sincronización gradle de estudio de android
  • Cómo importar reaccionar proyecto nativo en android studio
  • Cómo corregir estas advertencias proguard
  • Android Studio: Fallo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.