как остановить наблюдатель, который будет запущен более одного раза, когда viewmodel содержит значение от клиента? - PullRequest
0 голосов
/ 20 марта 2020

отказ от ответственности, этот вопрос отличается от моего предыдущего вопроса

Я новичок в MVVM и немного растерялся.

так что если пользователь нажимает кнопку в моем фрагменте, то я сделаю запрос к серверу, чтобы проверить, создал ли этот пользователь событие musi c или нет, если он не создал musi c событие, затем перейдите к фрагменту B. вот мой FragmentA

class FragmentA : Fragment() {

    lateinit var model: AViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        model = ViewModelProvider(this).get(AViewModel::class.java)


        button.setOnClickListener {
            model.checkIfUserHasCreatedEvent()
        }


        model.hasCreatedEvent.observe(this, Observer { hasCreatedEvent ->

            if (!hasCreatedEvent) {
                val chooseEventNameDestination = CreateEventFragmentDirections.actionToCreateEventName()
                findNavController().navigate(chooseEventNameDestination)
                model.navigationHasBeendHandled()
            }

        })



    }

}

и вот модель представления для этого фрагмента

class AViewModel(application: Application) : AndroidViewModel(application) {

    val _hasCreatedEvent : MutableLiveData<Boolean> = UserClient.hasCreatedEvent
    val hasCreatedEvent : LiveData<Boolean>
       get() = _hasCreatedEvent

    fun checkIfUserHasCreatedEvent() {
        UserClient.checkIfUserHasCreatedAnEvent()

    }

    fun navigationHasBeendHandled() {
        _hasCreatedEvent.value = true // to reset data, to avoid the value to be false
    }


}

, а вот UserClient (для простоты я пропускаю репозиторий )

object UserClient {

    val hasCreatedEvent = MutableLiveData<Boolean>()

    fun checkIfUserHasCreatedAnEvent() {

        // perform networking to server ....
        // and post the value after getting the response

        hasCreatedEvent.postValue(result)

    }


}

когда я впервые нажимаю кнопку, она работает как положено, она перемещается от фрагмента А к фрагменту Б., потому что после проверки на сервере hasCreatedEvent == false.

проблема происходит, когда я возвращаюсь от фрагмента B к фрагменту A.

, когда я возвращаюсь от фрагмента B, наблюдатель во фрагменте A вызывается более одного раза, даже если я не нажимаю кнопку, он срабатывает автоматически.

    model.hasCreatedEvent.observe(this, Observer { hasCreatedEvent ->

        // triggered 3 times in here 

        Log.d("AViewModel","result: $hasCreatedEvent")

        // result: true
        // result: false  <--- the problem
        // result: true

        if (!hasCreatedEvent) {
            // because there is a false value ...
            // then this block is triggered, and it makes it moves to fragmentB again
        }



    })

Я считаю, что значение true взято из метода navigationHasBeendHandled из моей viewModel, но я не понимаю, почему снова появляется значение false, когда я возвращаюсь из фрагмента B во фрагмент A? хотя я не нажимаю кнопку

Я предполагаю, что значение false взято из UserClient.hasCreatedEvent, которое содержит значение после выполнения запроса от сервера.

, но я не знаю, как решить эта проблема, потому что это значение false заставляет его снова автоматически перемещаться во фрагмент B.

java или kotlin в порядке

Ответы [ 2 ]

0 голосов
/ 20 марта 2020

Вы можете удалить наблюдателя, как это, после того, как вы впервые его заметили. Вы можете попробовать это:

model.hasCreatedEvent.observe(this, Observer { hasCreatedEvent ->

            if (!hasCreatedEvent) {
                val chooseEventNameDestination = CreateEventFragmentDirections.actionToCreateEventName()
                findNavController().navigate(chooseEventNameDestination)
                model.navigationHasBeendHandled()

                model.hasCreateEvent.removeObservers(this)
            }

        })
0 голосов
/ 20 марта 2020

Потому что, когда вы вернетесь к FragmentA, viewModel был создан снова, а для java / kotlin начальное значение Boolean равно false. Простым решением является создание ViewModel для вашей Деятельности, но не Фрагментов, это то, что Google рекомендует, пусть viewModel следует LifeCycle Деятельности, и все фрагменты в этой Деятельности будут использовать эту ViewModel.

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