Home > Net >  Kotlin: MutableLiveData HashMap of ViewModel is not observed
Kotlin: MutableLiveData HashMap of ViewModel is not observed

Time:01-09

I want to check 2 EditText fields are filled or not in real time.

So I created ViewModel which has MutableLiveData<HashMap<String, Boolean>>.

class PhoneFillClass : ViewModel() {
    var _phoneFillCheck = MutableLiveData<HashMap<String, Boolean>>()
    var phoneFillCheck = _phoneFillCheck.value
init {
    phoneFillCheck = hashMapOf(
        "first" to false,
        "second" to false,
    )
}

fun changePhoneFill(field: String, fill: Boolean) {
    phoneFillCheck?.set(field, fill)

   }
}

This hasMap has two objects in map, first and second. And Both are initiated as false.

If EditTexts text length becomes 4, I will make each first or second key's value changed to true.

 binding.phoneInput1.addTextChangedListener(object : TextWatcher {

        override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            //null
        }

        override fun onTextChanged(char: CharSequence?, start: Int, before: Int, count: Int) {

            if (char?.length == 4) {
                binding.errorMessage.visibility = View.GONE
                phoneTxtCheck.changePhoneFill("first", true)
            } else {
                binding.errorMessage.visibility = View.VISIBLE
                phoneTxtCheck.changePhoneFill("first", false)
            }
        }

            override fun afterTextChanged(p0: Editable?) {
        // null
    }
})

Like above, phoneTxtCheck.changePhoneFill("first", true) this line changes value of first key of MutableLiveData.

And I register this ViewModel.

    phoneTxtCheck._phoneFillCheck.observeForever(Observer { value ->
        Log.d("9th", "$value")
        binding.phoneAuthBtn.isEnabled = (value["first"] == true && value["second"] == true)
    })

So that if both of "first" and "second" 's values become true, I will enable Button.

But It doesn't work and when I Log value from observeForever, It prints nothing.

I'm not familiar with MutableLiveData and ViewModel in Kotlin, Please let me know which part is wrong in my code.

Thank you!

CodePudding user response:

You can create two mutable live data object can observe according to use.

in ViewModel create two object.

val editText1 by lazy { MutableLiveData<Boolean>(false)}
val editText2 by lazy { MutableLiveData<Boolean>(false)}

in activity update the value when your editText condition satisfied

viewModel.editText1.value = true

Observe the changes in the mutableLiveData

viewModel.editText1.observe( this@ActivityName ){ value ->
    binding.phoneAuthBtn.isEnabled = viewModel.editText1.value && viewModel.editText2.value
}

CodePudding user response:

Livedata will trigger the observer method when value inside the livedata is changed

you can change your code into something like this

fun changePhoneFill(field: String, fill: Boolean) {
    phoneFillCheck?.set(field, fill)
    _phoneFillCheck.value = phoneFillCheck
   }
}

also, there is few of the code you provided can be improved, such as :

  • use observe instead observerForever

    observe take additional parameter of viewLifecycleOwner, so livedata can avoid trigger the callback when activity/fragment no longer in active state, thus avoiding memory leak

  • use doOnTextChanged instead of addTextChangedListener

    doOnTextChanged provide the same functionality with addTextChangedListener#onTextChanged without overriding the other 2 method

CodePudding user response:

Change

init {
    phoneFillCheck = hashMapOf(
        "first" to false,
        "second" to false,
    )
}

to

init {
    _phoneFillCheck.value = hashMapOf(
        "first" to false,
        "second" to false,
    )
}

and observe phoneFillCheck.

  • Related