Как наблюдать за 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)


arrow_upward
0
arrow_downward

Последний 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