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 EditText
s 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
insteadobserverForever
observe
take additional parameter ofviewLifecycleOwner
, so livedata can avoid trigger the callback when activity/fragment no longer in active state, thus avoiding memory leakuse
doOnTextChanged
instead ofaddTextChangedListener
doOnTextChanged
provide the same functionality withaddTextChangedListener#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
.