Reputation: 182
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
fun
ctions and cannot be override
n?
How can I make this property expose through fun
ctions?
Upvotes: 0
Views: 1034
Reputation: 583
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.
Upvotes: 1
Reputation: 182
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
Upvotes: 0
Reputation: 12138
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
}
Upvotes: 0