Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Databinding variable inheritance with included layout

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.

like image 278
Daniel Wilson Avatar asked Oct 25 '17 09:10

Daniel Wilson


People also ask

Is databinding better than findViewById method?

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.

Can I use both databinding and ViewBinding?

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.

Which of the following is included in 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.

What is Br class in data binding?

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.

How to pass a value to included layout in data binding?

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.

How to generate a binding class for a 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 a variable ID?

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.

What is data binding in Android?

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.


1 Answers

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>
like image 172
Aleyam Avatar answered Oct 12 '22 22:10

Aleyam