Как наблюдать за Emited LiveData с помощью MVVM

Я изо всех сил пытаюсь понять, как обрабатывать выпущенные liveData. Я написал здесь четыре разных примера liveData,

class MainViewModel : ViewModel() {
    val viewModelValue = MyRepo.liveValue
    fun viewModelGetNextValue(){
        MyRepo.getNextValue()
    }

    val viewModelSquareValue = MyRepo.squareLiveValue
    fun viewModelGetSquareValue(x:Int){
        MyRepo.getSquareValue(x)
    }

    val viewModelEmitValue = MyRepo.emitLiveValue

    lateinit var viewModelEmitFunctionValue:LiveData<String>
    fun viewModelEmitLiveFunction(x:Int){
        viewModelEmitFunctionValue = MyRepo.emitLiveFunction(x)
    }
}

object MyRepo{
    var value = 1

    val liveValue = MutableLiveData<Int>()
    fun getNextValue(){
        liveValue.postValue(++value)
    }

    val squareLiveValue = MutableLiveData<Int>()
    fun getSquareValue(x:Int){
        squareLiveValue.postValue(x*x)
    }

    val emitLiveValue = liveData {
        emit("First Emit")
        delay(2000)
        emit("second value")
    }

    fun emitLiveFunction(x:Int) = liveData {
        emit("value: $x")
        delay(2000)
        emit("square: ${x*x}")
    }
}

И часть кода фрагмента:

        viewModel.viewModelValue.observe(viewLifecycleOwner, Observer {
            Toast.makeText(activity, "$it", Toast.LENGTH_SHORT).show()
        })
        viewModel.viewModelSquareValue.observe(viewLifecycleOwner, Observer {
            Toast.makeText(activity, "$it", Toast.LENGTH_SHORT).show()
            viewModel.viewModelSquareValue.removeObservers(viewLifecycleOwner)
        })
        viewModel.viewModelEmitValue.observe(viewLifecycleOwner, Observer {
            Toast.makeText(activity, it, Toast.LENGTH_SHORT).show()
        })

        button1.setOnClickListener { viewModel.viewModelGetNextValue() }
        button2.setOnClickListener { viewModel.viewModelGetSquareValue(++x) }
        button3.setOnClickListener {
            viewModel.viewModelEmitLiveFunction(++x)
            viewModel.viewModelEmitFunctionValue.observe(viewLifecycleOwner, Observer {
                Toast.makeText(activity, it, Toast.LENGTH_SHORT).show()
            })
        }

Первые два примера LiveData (viewModelValue и viewModelSquareValue) легко заметить. и может быть вызван с помощью прослушивателя нажатия кнопки. Третья liveata viewModelEmitValue, где я использовал emit, автоматически показывает значение.

Что мне делать, если мне нужны эти значения после нажатия кнопки? Мне просто нужно написать код наблюдателя в прослушивателе кликов?

Последний liveData viewModelEmitFunctionValue работает. Но разве это единственный способ (с использованием lateinit var) получить значение, если я хочу получить его после нажатия кнопки?


person sadat    schedule 10.02.2020    source источник


Ответы (1)


Последний liveData viewModelEmitFunctionValue работает. Но является ли это единственным способом (с использованием lateinit var) получить значение, если я хочу получить его после нажатия кнопки?

Таким образом, вы создаете наблюдателей для каждого нажатия кнопки, добавляя дополнительный тост каждый второй щелчок. Хорошая новость заключается в том, что вы также создаете экземпляр LiveData с каждым щелчком, чтобы предыдущие наблюдатели очистились. Но это немного запутанный подход.

val emitLiveValue = liveData { - это не ленивый способ объявить LiveData, поэтому после инициализации Repo он начинает выполнение кода внутри liveData{}

В случае fun emitLiveFunction(x:Int) = liveData { вы создаете LiveData только в момент вызова функции, поэтому она хорошо работает.

Я предлагаю хранить x значение в живых данных и вычислять emitLiveFunction при каждом его изменении. Вы можете добиться этого с помощью Transformations.switchMap

class MainViewModel : ViewModel() {
...
  private val x = MutableLiveData<Int>()
  val functionResult = x.switchMap { MyRepo.emitLiveFunction(it) }

  fun viewModelEmitLiveFunction(x:Int) { 
      this.x.postValue(x)
  }
}

Теперь вы можете добавить наблюдателя в functionResult сразу после создания действия и вызвать viewModelEmitLiveFunction(x) при нажатии кнопки 3, вы инициируете выполнение функции репо с новым значением x

person Alex Krafts    schedule 26.02.2020