Я столкнулся с проблемой при работе с компонентом навигации, ViewModel
& LiveData
.
Я наблюдаю ответ от сервера в MatchDetailFragment
, и после получения ответа от сервера мой MatchDetailFragment
получает уведомление об изменении наблюдаемых данных в реальном времени, и я перехожу к ScoreFragment
, но когда я возвращаюсь к MatchDetailFragment
, Наблюдаемый ответ получает уведомление снова и пытается перейти к MatchDetailFragment
снова, и приложение падает, потому что пункт назначения findNavController()
по-прежнему MatchDetailFragment
, и он пытается перейти к nextDestination
, который не определен в MatchDetailFragment
Теперь, во-первых, мой LiveData
должен получать уведомления, когда я просто нажимаю backstack, потому что мне нужно перейти к фрагменту B на основе ответа
Вот соответствующий код
MatchDetailFragment
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding: FragmentMatchDetailBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_match_detail, container, false)
matchDetailViewModel = ViewModelProviders.of(this).get(MatchDetailViewModel::class.java)
binding.matchDetailViewModel = matchDetailViewModel
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
matchDetailViewModel.matchDetail.value = args.selctedMatch
matchDetailViewModel.newMatchSetResponse.observe(viewLifecycleOwner, Observer { resource ->
when (resource) {
is Resource.Loading -> {
showLoading()
}
is Resource.Success -> {
hideLoading()
with(resource.data) {
if (this.body() != null) {
val nextDestination = MatchDetailFragmentDirections.nextAction(this.body()!!, args.selctedMatch)
findNavController().navigate(nextDestination)
} else {
root.showSnackbar(this.message(), Snackbar.LENGTH_LONG)
}
}
}
is Resource.Failure -> {
hideLoading()
root.showSnackbar("Error occurred", Snackbar.LENGTH_LONG)
}
}
})
}
ScoreFragment
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding: FragmentScoreBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_score, container, false)
binding.match = args.matchDetail
binding.setResponse = args.matchSetResponse
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
scoreViewModel = ViewModelProviders.of(this).get(ScoreViewModel::class.java)
}