I have ViewModel:
class MyViewModel : ViewModel(){
private val _user = MutableLiveData("")
val user: LiveData<String> = _user
fun onBtnClick(){
Log.i("MyViewModel", "user: ${_user.value}")
}
}
I connected it with fragment layout using:
<data>
<variable
name="viewmodel"
type="com.pkg.pkg.pkg.fragments.concretePkg.MyViewModel" />
</data>
<EditText
...
android:text="@={viewmodel.user}"
android:hint="User" />
And in fragment class in onCreateView method:
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_my_fragment, container, false)
binding.lifecycleOwner = this
// bind viewModel
viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
binding.viewmodel = viewModel
// Inflate the layout for this fragment
return binding.root
I can change the EditText value from the fragment or ViewModel class, but when I try to get the value inside the onBtnClick method of the ViewModel in the Logcat I am getting the message: I/MyViewModel: user:
What am I missing here so that two-way data binding works from the other direction too?
I nutshell, data goes from ViewModel/ Fragment to EditText on the interface, but it doesn't flow from EditText on the interface to ViewModel fields/ methods.
Thanks in advance.
------- EDITED ----- I managed to populate everything, but know I am getting this error:
Details: There is no inverse for method getValue, you must add an @InverseMethod annotation to the method to indicate which method should be used when using it in two-way binding expressions
I suppose that is because viewmodel.user is of type LiveData and not of a String. I have written binding adapter:
@BindingAdapter("android:text")
fun setLiveDataText(editText: EditText, liveData: LiveData<String>) {
if(liveData == null){
editText.setText("")
} else {
editText.setText(liveData.value)
}
}
But I am still getting the above message.
First, you need to make
_userpublic. Then you need to use"@={viewmodel._user}", so that you can get the value of_user. Databinding API can't figure out and generate code if you don't make your databinding variable public. For simple fields such as Strings, this approach will suffice, but you may have to implementBindingAdaptersfor more complex situations. See this article for examples.