0

I am implementing Two-Way DataBinding with Android Architecture Components using LiveData and ViewModel, but when I build the project it gives

error: cannot find symbol
import package.[layout_name]BindingImpl;

in DataBinderMapperImpl.java

I followed official documentation and looked at SO for answers but none of them had workable solutions.

already tried this one and this one

layout.xml

    <data>
        <import type="package.ViewModel" /> // this line was added from an answer but didn't work
        <variable
            name="model"
            type="package.ViewModel"/>
    </data>

// an input field I want to bind data with
<androidx.appcompat.widget.AppCompatAutoCompleteTextView
                    android:id="@+id/email"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@={model.email}" // if I remove this line, builds fine
                    android:hint="@string/prompt_email"
                    android:inputType="textEmailAddress"
                    android:maxLines="1"
                    android:singleLine="true" />

Extending my ViewModel from AndroidViewModel instead of BaseObservable as mentioned in documentation

ViewModel.kt

    private val email: MutableLiveData<String> by lazy { MutableLiveData<String>() }
    @Bindable // tried to change the return type to String, still no luck
    fun getEmail(): LiveData<String> {
        return email
    }

    fun setEmail(email: String) {
        this.email.value = email
    }

This is how I bind ViewModel with View

Activity.kt

binding.model = ViewModelProviders.of(this, ViewModelProvider.AndroidViewModelFactory
            .getInstance(application))
            .get(LoginViewModel::class.java)

What am I missing? Already included all things pre-databinding and if I had replaced ViewModel in layout with a data class and tried to get data from it, that works fine but with @{} in layout

EDIT

Okay, so when I expose email as public, it compiles and binding works, but I can't make its setter and getter public, I mean when I try to expose it from its getter and setter, IDE says that these are already private functions and cannot be overriden?

How can I make this property expose through functions?

3 Answers 3

1

I was having the same problem and none of the solutions presented here worked. In my case, the problem was because I had a Double property.

I changed it to String and it worked.

Sign up to request clarification or add additional context in comments.

1 Comment

This should be the accepted answer. I had a MutableLiveData<Int> and it was not working. I changed it to MutableLiveData<String> and it compiled! Thank you!
0

You can use getter of particular variable directly using get() method to variable (also works for setter too as set(value)) like below :

@get:Bindable // We make getter method bindable for data-binding
val email = MutableLiveData<String>()
    get() { // Try to provide getter method like this
        return field as LiveData<String>
    }
    set(data) { // Try to provide setter method like this
        if(field.value != data.value) // To avoid infinite loop
            field.value = data.value
    }

1 Comment

thanks but for two-way binding to work you have to expose the field as MutableLiveData and make it default
0

Found the answer on Reddit.

For two-way databinding to work, you have to expose your fields and they should be MutableLiveData like

val email = MutableLiveData<String>()

since kotlin already has get and set properties, they'll be used by Binding classes for fields

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.