Я хочу проверить, заполнены ли 2 поля EditText или нет в режиме реального времени.
Поэтому я создал ViewModel
, у которого есть 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)
}
}
Этот hasMap имеет два объекта на карте, первый и второй.
И Оба инициированы как false
.
Если длина текста EditText
s станет равной 4, я изменю значение каждого первого или второго ключа на 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
}
})
Как и выше, phoneTxtCheck.changePhoneFill("first", true)
эта строка изменяет значение первого ключа MutableLiveData.
И я регистрирую эту ViewModel.
phoneTxtCheck._phoneFillCheck.observeForever(Observer { value ->
Log.d("9th", "$value")
binding.phoneAuthBtn.isEnabled = (value["first"] == true && value["second"] == true)
})
Так что, если оба значения "first" и "second" станут истинными, я включу Button.
Но это не работает, и когда я вхожу в журнал value
изObserverForever, он ничего не печатает.
Я не знаком с MutableLiveData и ViewModel в Kotlin. Пожалуйста, дайте мне знать, какая часть моего кода неверна.
Спасибо!
Вы можете создать два изменяемых объекта живых данных, которые можно наблюдать в зависимости от использования.
в ViewModel создайте два объекта.
val editText1 by lazy { MutableLiveData<Boolean>(false)}
val editText2 by lazy { MutableLiveData<Boolean>(false)}
в действии обновите значение, когда ваше условие editText выполнено
viewModel.editText1.value = true
Наблюдайте за изменениями в mutableLiveData
viewModel.editText1.observe( this@ActivityName ){ value ->
binding.phoneAuthBtn.isEnabled = viewModel.editText1.value && viewModel.editText2.value
}
Изменять
init {
phoneFillCheck = hashMapOf(
"first" to false,
"second" to false,
)
}
к
init {
_phoneFillCheck.value = hashMapOf(
"first" to false,
"second" to false,
)
}
и наблюдайте phoneFillCheck
.
Я сделал это, но все еще не работает
Также измените phoneFillCheck?.set(field, fill)
на _phoneFillCheck.value!!.set(field, fill)
Livedata вызовет метод наблюдателя, когда значение внутри livedata изменится
вы можете изменить свой код на что-то вроде этого
fun changePhoneFill(field: String, fill: Boolean) {
phoneFillCheck?.set(field, fill)
_phoneFillCheck.value = phoneFillCheck
}
}
Кроме того, есть несколько предоставленных вами кодов, которые можно улучшить, например:
используйте observe
вместо observerForever
observe
принимает дополнительный параметр viewLifecycleOwner
, поэтому livedata может избежать запуска обратного вызова, когда активность/фрагмент больше не находится в активном состоянии, что позволяет избежать утечки памяти
используйте doOnTextChanged
вместо addTextChangedListener
doOnTextChanged
обеспечивает ту же функциональность с addTextChangedListener#onTextChanged
без переопределения двух других методов
оно работает! Спасибо. Мне любопытно, почему hashmap не работает, даже если я меняю код по мнению @sajidjuneja