Как вернуть LiveData из репозитория - PullRequest
0 голосов
/ 23 января 2020

Я просто не вижу, как связать LiveData от Repo до VM, поэтому я попытался свести это к самому простому примеру!

Фрагмент

class LoginFragment : Fragment() {

private lateinit var loginViewModel: LoginViewModel
private var mCurrentName = "Blank!"

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    val binding: LoginFragmentBinding = DataBindingUtil.inflate(
        inflater, R.layout.login_fragment, container, false)

    binding.apply {
        loginButton.setOnClickListener{
            loginViewModel.changeText()
        }
    }
    return binding.root
}


override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    loginViewModel = ViewModelProviders.of(this).get(LoginViewModel::class.java)

    loginViewModel.getCurrentName().observe(viewLifecycleOwner, Observer {
        mCurrentName = it      // I'm expecting mCurrentName to equal "Button Clicked!" when button clicked..
        makeToast()     // Toast works, but variable remains unchanged..
    })

}

private fun makeToast() {
    Toast.makeText(activity, mCurrentName, Toast.LENGTH_LONG).show()
}

ViewModel

class LoginViewModel : ViewModel() {

private val firestoreRepository : FirestoreRepository = FirestoreRepository()
private var mCurrentName = MutableLiveData<String>()

fun changeText(){
    mCurrentName = firestoreRepository.changeText()
}

Репозиторий

class FirestoreRepository {

    private val mCurrentName = MutableLiveData<String>()

    fun changeText(): MutableLiveData<String> {
            mCurrentName.value = "Button Clicked!!"
            return mCurrentName
    }

Я предполагаю, что неправильно понял, как работает функция наблюдателя ..

Ответы [ 3 ]

1 голос
/ 23 января 2020

Не нужно менять MutableLiveData внутри ViewModel. Попробуйте передать все, что Repository отправить на View. Проверьте ниже

class LoginViewModel : ViewModel() {

    private val firestoreRepository : FirestoreRepository = FirestoreRepository()

    fun getCurrentName(): MutableLiveData<String> {
        return firestoreRepository.getCurrentName()
    }

    fun changeText() {
        firestoreRepository.changeText()
    }
}

А также ваш FirestoreRepository

class FirestoreRepository {

    private val mCurrentName = MutableLiveData<String>()

    fun getCurrentName(): MutableLiveData<String> {
        return mCurrentName
    }

    fun changeText() {
        mCurrentName.value = "Button Clicked!!"
    }
}
1 голос
/ 23 января 2020

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

  1. Класс активности: измените метод makeToast на наблюдающийCurrentName () следующим образом:

    private fun observeCurrentName() {
        vm.getCurrentName().observe(this, Observer{ 
            //Toast here 
        })
    }
    
  2. Ваша виртуальная машина:

    class LoginViewModel : ViewModel() {
        ...
    
        fun getCurrentName(): MutableLiveData<String>{
            return repository.getCurrentName()
        }
    
        fun setCurrentName(name: String?){
            repository.setCurrentName(name)
        }
    
        ...
    }
    
  3. Ваш репозиторий:

    class FirestoreRepository {
    
        private val mCurrentName = MutableLiveData<String>()
    
        fun getCurrentName(): MutableLiveData<String>{
            return mCurrentName
        }
    
        fun setCurrentName(name: String?){
            mCurrentName.value = name //This will trigger observer in Activity
        }
    }
    
0 голосов
/ 23 января 2020

Вы меняете mCurrentName (сама переменная LiveData, а не ее содержимое) после того, как вы начинаете наблюдать ее. Похоже, что руководство не должно использовать LiveData в слое Repository (вместо этого используйте Coroutines / Flow) .... но сейчас вы можете иметь что-то вроде следующего (или, возможно, использовать одно из преобразований LiveData)

private val mCurrentName = firestoreRepository.currentName()

fun changeText(){
    firestoreRepository.changeText()
}
...