Search code examples
androidviewmodelandroid-databindingandroid-livedatamutablelivedata

How to make data binding work with xml attributes?


I'm setting up my Edittext and CheckBox to hook with my view model. I've already setup the variables isActive and currentValue on my ViewModel, and I want to initialize their values to the xml so that when the user arrives at the Fragment, the current values are also set to the form fields.

I've already tried adding android:checked="@{viewModel.isActive}" to the CheckBox, and android:text="@{viewModel.currentValue}" to the EditText, however it produces no result.

Right now, my workaround is initializing the form field values through the Fragment:

viewModel.isActive.observe(this, Observer {
    it?.let {
        binding.checkBox.isChecked = it
    }
})
viewModel.currentValue.observe(this, Observer {
    it?.let {
        binding.editText.setText(it.toString())
    }
})

Here's my code:

ViewModel.kt

val isActive = Transformations.map(currentEntity) {
    it.value?.isActive == 1
}

val currentValue = Transformations.map(currentEntity) {
    it.value?.currentValue
}

private var currentEntity = MutableLiveData<Entity?>()
init {
    initializeCurrentEntity()
}

private fun initializeCurrentEntity() {
    uiScope.launch {
        currentEntity.value = getCurrentEntityById(id)
    }
}
layout.xml

<layout ...>
    <data>
        <variable name="viewModel"
                  type="com.example.app.ViewModel"/>
    </data>
    ...
    <com.google.android.material.textfield.TextInputLayout ... >
        <com.google.android.material.textfield.TextInputEditText  
            ...
            android:text="@{viewModel.currentValue}"
            ...
            />
    </com.google.android.material.textfield.TextInputLayout>
    ...
    <CheckBox
        ...
        android:checked="@{viewModel.isActive}" />
</layout>

My desired result is that, when the viewModel has already initialized the currentEntity and updated the isActive and currentValue, it would also reflect in the xml. I think that the actual outputs as of now is null for both the currentValue and isActive


Solution

  • It seems that I have forgotten to set the LifecycleOwner to the data binding. I have fixed it with binding.setLifecycleOwner(this) on my Fragment.