Как наблюдать Emited LiveData с MVVM - PullRequest
0 голосов
/ 10 февраля 2020

Я изо всех сил пытаюсь понять, как обрабатывать испускаемые 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) это легко наблюдать. и может быть вызван слушателем щелчка кнопки. Третья жилата viewModelEmitValue, где я использовал emit, автоматически показывает значение.

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

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

1 Ответ

0 голосов
/ 26 февраля 2020

Последнее представление 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...