Как обрабатывать фрагменты, совместно использующие одну и ту же модель представления и жилые данные, вызывающие одинаковые действия на обоих фрагментах? - PullRequest
1 голос
/ 04 мая 2020

У меня есть SignUpFragment, в котором для регистрации используется Firebase, и есть наблюдатель liveata.

SignUpFragment

    viewModel.userMediatorLiveData.observe(this, Observer {
        Timber.i("Screen", this.javaClass.simpleName)
        if (it.status != null && it.message != null) {
            btn_sign_up.showSnack(it.message)
            if (it.status) {
                PreferenceHelper.userPassword = tie_password.getTrimmedText()
                returnToLoginScreen()
            }
        }
    })

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

LoginFragment

    // this observer is used also for listening to Firebase Login
    viewModel.userMediatorLiveData.observe(this, Observer {
        Timber.i("Screen", this.javaClass.simpleName)
        if (it.status != null && it.message != null) {
            btn_login.showSnack(it.message)
            if (it.status) {
                PreferenceHelper.userPassword = tie_password.getTrimmedText()
                context?.startActivity(HomeActivity::class.java)
                requireActivity().finish()
            }
        }
    })

Здесь вы можете видеть, что условие будет истинным для обоих случаев и Экран входа в систему переключается на HomeScreen.

Как я могу справиться с такой ситуацией? Обратите внимание, что я делюсь viewmodel, используя

 private val viewModel: AuthViewModel by activityViewModels()

Также заменен this на viewLifecycleOwner, но все еще нет надежды.

1 Ответ

1 голос
/ 04 мая 2020

Итак, продолжая наше обсуждение здесь, вы делитесь ViewModel между фрагментами, поэтому, когда вы наблюдаете конкретные живые данные во фрагменте, вы не реинициализируете их, а используете один и тот же экземпляр. Таким образом, есть два способа справиться с этим. Первый: прекратите совместное использование вашей ViewModel или удалите наблюдателя, как только вы измените флаг.

это 2-й способ:

val mUserData = viewModel.userMediatorLiveData

val mUserObserver = Observer {
    Timber.i("Screen", this.javaClass.simpleName)
    if (it.status != null && it.message != null) {
        btn_login.showSnack(it.message)
        if (it.status) {
            PreferenceHelper.userPassword = tie_password.getTrimmedText()
            context?.startActivity(HomeActivity::class.java)
            requireActivity().finish()
            //notice this
            mUserData.removeObserver(mUserObserver)
        }
    }
}

mUserData.observe(viewLifecycleOwner, mUserObserver)

Возможно, вам придется сначала определить свой mUserObserver (вне функция).

Попробуйте и дайте мне знать

...