Search code examples
androiddata-bindingviewmodel

Cannot call method ViewModel isValidate() from xml with dataBinding


This disabling of the button works correctly with the use of binding expressions, but when it is very long I need to move it to a method in the ViewModel, that is where it does not work correctly.

<com.google.android.material.button.MaterialButton
    android: id = "@ + id / btValidateLegalRepresentativeCE"
    style = "@ style / BasicMaterialButton"
    android: layout_width = "match_parent"
    android: layout_marginTop = "21dp"
    android: enabled = "@ {viewModel.documentLiveData.length()> 0 &amp; viewModel.firstNameLiveData.length()> 0 &amp; viewModel.lastNameLiveData.length()> 0} "

Method call from the ViewModel

<com.google.android.material.button.MaterialButton
    android: id = "@ + id / btValidateLegalRepresentativeCE"
        style = "@ style / BasicMaterialButton"
        android: layout_width = "match_parent"
        android: layout_marginTop = "21dp"
        app: enabled = "@ {viewModel.isValidate()}" />

ViewModel

private val _documentLiveData = MutableLiveData("")
val documentLiveData: MutableLiveData<String> get() = _documentLiveData

private val _firstNameLiveData = MutableLiveData("")
val firstNameLiveData: LiveData<String> get() = _firstNameLiveData

private val _lastNameLiveData = MutableLiveData("")
val lastNameLiveData: LiveData<String> get() = _lastNameLiveData

fun isValidate(): Boolean {
    val document = documentLiveData.value?.length ?: 0
    val firstName = firstNameLiveData.value?.length ?: 0
    val lastName = lastNameLiveData.value?.length ?: 0
    return (document > 0) && (firstName > 0) && (lastName > 0)
}

I consider the following:

binding.viewModel = viewModel

binding.lifecycleOwner = this

Thanks for the help.


Solution

  • To call function within viewmodel,you need to use ()->

    app:enabled = "@ {()->viewModel.isValidate()}
    

    if above method not working, create custom binding adapter.

    In java ,it will be like

     @androidx.databinding.BindingAdapter("android:viewModel")
    public static void setButtonEnable(Button button,YourViewModel viewModel) {
         if(viewModel.isValidate())
          //if true ,enable button
          button.setEnable(true);
         
      else 
        //disable button
         button.setEnable(false);
         }
    

    call this custom adapter from layout and pass viewmodel into adapter.

    <com.google.android.material.button.MaterialButton
        android: id = "@ + id / btValidateLegalRepresentativeCE"
            style = "@ style / BasicMaterialButton"
            android: layout_width = "match_parent"
            android: layout_marginTop = "21dp"
            android:viewModel= "@{viewModel}" />