Kotlin: MutableLiveData HashMap ViewModel не наблюдается

Я хочу проверить, заполнены ли 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.

Если длина текста EditTexts станет равной 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. Пожалуйста, дайте мне знать, какая часть моего кода неверна.

Спасибо!

0
0
52
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете создать два изменяемых объекта живых данных, которые можно наблюдать в зависимости от использования.

в 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
}

оно работает! Спасибо. Мне любопытно, почему hashmap не работает, даже если я меняю код по мнению @sajidjuneja

Hyejung 09.01.2023 07:37

Изменять

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

к

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

и наблюдайте phoneFillCheck.

Я сделал это, но все еще не работает

Hyejung 09.01.2023 07:31

Также измените phoneFillCheck?.set(field, fill) на _phoneFillCheck.value!!.set(field, fill)

sajidjuneja 09.01.2023 07:39

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 без переопределения двух других методов

Другие вопросы по теме

Из какой зависимости исходит моя дублирующая привязка Slf4j в этом дереве зависимостей maven?
Как преобразовать массив битов в байт (а не в байтовую строку)?
Android kotlin crossinline возвращается из лямбда
Ползунок «Создать» должен реагировать на ручные изменения и изменения значений из внешнего источника
Пользовательский объект kotlin правила lint
Как в IntelliJ IDEA правильно создавать и выполнять сценарии kotlin (.kts), которые зависят от кода в моем проекте?
Kotlin, изменяющий ключ объекта класса данных с карты, изменяет ссылку после изменения переменной
Как прослушивать события javascript из собственного приложения для Android?
Ни одна из следующих функций не может быть вызвана с указанными аргументами | Вызовы @Composable могут происходить только из контекста @Composable
Как заставить этот треугольный индикатор вращаться и двигаться в составе реактивного ранца Android?