Метод наблюдения() ViewModel не наблюдает должным образом

Я делаю приложение, используя MVVM pattern.

Я реализую функцию добавления элемента в recycler view при нажатии кнопки, но получаю от наблюдателя ошибку NullPointException. (Если быть точным, вы нажимаете кнопку для переключения экранов и добавления элементов на основе полученного аргумента.)

Что пошло не так..?

Я сослался на это

В фрагменте

override fun onViewCreated(view: View, savedInstanceState
: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        args.workout?.let {
            viewModel.addItem()
        }

        viewModel.item.observe(viewLifecycleOwner) { newItem ->
            adapter.setItems(newItem) // error
        }
    }

Модель представления

class WriteRoutineViewModel : ViewModel() {
    private var _item: MutableLiveData<ArrayList<RoutineModel>> = MutableLiveData()
    val item: LiveData<ArrayList<RoutineModel>> = _item

    fun addItem() {
        _item.value?.add(RoutineModel("test", "ABC"))
        _item.value = _item.value
    }
}

ОШИБКА

2021-07-15 04:26:25.961 13731-13731/com.example.writeweight E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.writeweight, PID: 13731
    java.lang.NullPointerException: newItem must not be null
        at com.example.writeweight.fragment.WriteRoutineFragment$onViewCreated$4.onChanged(WriteRoutineFragment.kt:66)
        at com.example.writeweight.fragment.WriteRoutineFragment$onViewCreated$4.onChanged(WriteRoutineFragment.kt:18)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:146)
        at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:468)
        at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:425)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
        at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:265)


person ybybyb    schedule 14.07.2021    source источник


Ответы (1)


Проблема здесь в том, что MutableLiveData<ArrayList<RoutineModel>> установлено только на MutableLiveData(), попробуйте изменить его на MutableLiveData(arrayListOf()), должно сработать :)

РЕДАКТИРОВАТЬ:

Причина проста, ArrayList требует инициализации даже внутри оболочки MutableLiveData вокруг него.

person mehul bisht    schedule 14.07.2021
comment
Нет, либо вы можете каждый раз проверять внутри метода add(), если _item.value != null, и только затем добавлять элемент, иначе инициализировать его с помощью _item = arrayListOf(), поскольку он не инициализируется сам по себе, и, если вы это поняли, пожалуйста, отметьте мой ответ как принятый решение :) - person mehul bisht; 14.07.2021
comment
Ха-ха .. Я писал, чтобы спросить, почему это так, но вы исправили ответ на это! Итак, помимо инициализации MutableLiveData, нужно также инициализировать ArrayList<RoutineModel>, верно? - person ybybyb; 14.07.2021
comment
да, в основном все внутри оболочки MutableLiveData необходимо инициализировать перед использованием ее значения :) - person mehul bisht; 14.07.2021
comment
Хорошо, я понимаю эту часть. Итак, почему шаг _item.value?.add(RoutineModel("test", "ABC")) не вызывает ошибку? ArrayList<RoutineModel> внутри MutableLiveData не инициализирован, почему add() не выдает ошибку? - person ybybyb; 14.07.2021
comment
LiveData.value возвращает версию значения, допускающую значение NULL. Возвращаемое значение равно null, если начальное значение еще не установлено. Когда вы используете оператор вызова nullsafe ?. и значение равно null, add не вызывается, потому что его не на чем вызывать. - person Tenfour04; 14.07.2021
comment
@ Tenfour04 о! Проблема была в вызове безопасности! Теперь я понимаю это правильно. Большое спасибо. Я все еще далеко. Хорошего дня - person ybybyb; 14.07.2021