I am learning data binding and mvvm. I have an issue where I would like a BaseViewModel.kt
to include some UI related variables such as an isLoading
flag and loadingText
. When a network request is made, I set isLoading
to true and some child of my base view model should set the text. For example for a LoginViewModel.kt
the text might be 'logging in'. Is it possible to pass these variables to an included base layout?
So a login_activity.xml
might include this in it's layout:
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="core.sdk.ui.login.LoginViewModel" />
</data>
<!-- Various click listeners using the viewModel variable -->
<include
android:id="@+id/progress_include"
layout="@layout/progress_bar"
android:visibility="@{viewModel.isLoading ? View.VISIBLE : View.GONE}"
bind:viewModel="@{viewModel}"/>
Now I want my progress_bar.xml
to be nice and generic and use the base view model:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="core.sdk.ui.login.LoginActivity">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="core.sdk.ui.base.BaseViewModel" />
</data>
<LinearLayout
android:id="@+id/circular_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<android.support.v4.widget.ContentLoadingProgressBar
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/progress_text"
style="@style/TextAppearance.AppCompat.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-thin"
android:gravity="center_horizontal"
android:text="@{viewModel.loadingText}"
android:textStyle="italic"
tools:text="loading..." />
</LinearLayout>
The error I get is something like
****/ data binding error ****msg:Cannot find the setter for attribute 'bind:viewModel' with parameter type core.sdk.ui.login.LoginViewModel
If this isn't possible the only alternative I can see is to remove the include and copy and paste the progress bar + text to every view model which isn't very nice.
Databinding is really faster compared to findViewById and setText . Not only performance, It is also much faster and maintainable for mid, full-scale projects. As a side note, benefits include: performance.
View binding doesn't support layout variables or layout expressions, so it can't be used to declare dynamic UI content straight from XML layout files. View binding doesn't support two-way data binding.
Android Studio Supports Data Binding For example, it supports the following features for data binding expressions: Syntax Highlighting. XML code completion. Flagging of expression language syntax errors.
The BindingHolder object has a getBinding() method returning the ViewDataBinding base class. Note: The Data Binding Library generates a class named BR in the module package which contains the IDs of the resources used for data binding. In the example above, the library automatically generates the BR. item variable.
It adds "Data binding doesn't support include as a direct child of a merge element" Just set id to included layout, and use binding.includedLayout.anyView. This example helps passing a value to <include & accessing included views in code. You have layout_common.xml, want to pass String to included layout.
A binding class is generated for each layout file. By default, the name of the class is based on the name of the layout file, converting it to Pascal case and adding the Binding suffix to it. The above layout filename is activity_main.xml so the corresponding generated class is ActivityMainBinding.
Will generate a binding class with: IDs are not nearly as necessary as without data binding, but there are still some instances where access to Views are still necessary from code. Each variable will be given accessor methods.
Introduction Data Binding is a Library, part of Android Jetpack that provides flexibility to bind the UI components in XML layout files to data sources in class files using a declarative format. In the previous post, we have seen how to integrate the Data Binding Library and its basic usage of setting data and handling events.
for those who still don't have solution, just check your code and check whether the name of "bind" attribute is same as the one used in the included layout
<include
...
bind:viewModel="@{viewModel}"/>
and
<data>
...
<variable
name="viewModel"
type="core.sdk.ui.base.BaseViewModel" />
</data>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With