LiveData не устанавливается, наблюдатель никогда не вызывается
Я пытаюсь сохранить "Эпизод" в моем MainViewModel
и позволить другим Fragments
иметь доступ к нему через это ViewModel
,
В MainActivity
Я наблюдаю изменения в ViewModel
, который никогда не срабатывает. Странно, но он отлично работает для моего объекта RSS MainFeed
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(MainViewModel::class.java)
mViewModel?.getMainFeed()
setFragment(EpisodesFragment(), false)
mViewModel?.episode?.observe(this, Observer {
Log.d(TAG, "HERE 123")
})
}
Вот MainViewModel
:
class MainViewModel @Inject constructor(): ViewModel() {
val TAG: String? = MainViewModel::class.simpleName
@Inject lateinit var api: NetworkModule
var mainFeed: MutableLiveData<Response<RSS>> = MutableLiveData()
var episode: MutableLiveData<Item> = MutableLiveData()
companion object{
fun create(activity: FragmentActivity, viewModelFactory: ViewModelProvider.Factory): MainViewModel {
return ViewModelProviders.of(activity, viewModelFactory).get(MainViewModel::class.java)
}
}
fun getMainFeed(){
GlobalScope.launch(Dispatchers.Main) {
val request = api.getRssFeed()
val response = request.await()
if(response.isSuccessful){
Log.d(TAG, "isSuccessful")
mainFeed.value = response
} else {
Log.d(TAG, "not successful")
}
}
}
fun setEpisode(item: Item?){
Log.d(TAG, item?.description)
episode?.value = item
}
}
В моем EpisodesFragment
Я прохожу MainViewModel
к RecyclerView
адаптер. В макете для элемента Эпизод у меня есть onClick()
что вызывает mViewModel.setEpisode(episode)
Так что клики регистрируются. Я установил контрольные точки и вижу, что элемент эпизода действительно находится там и хранит данные в setEpisode()
метод. Это просто никогда не устанавливается в LiveData
, Я проверил, что ViewModel
не является нулевым в любых местах, где я его использовал.
Редактировать: Добавление кода для EpisodesFragment
class EpisodesFragment @Inject constructor() : DaggerFragment() {
var TAG: String? = EpisodesFragment::class.simpleName
var mBinding: FragmentEpisodesBinding? = null
var mRV: RecyclerView? = null
var mAdapter: EpisodesRecyclerViewAdapter? = null
var mItems: MutableList<Item> = ArrayList<Item>()
@Inject
lateinit var mViewModelFactory: ViewModelProvider.Factory
var mViewModel: EpisodesViewModel? = null
var mMainViewModel: MainViewModel? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_episodes, container, false)
mBinding?.executePendingBindings()
return mBinding?.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mViewModel = ViewModelProviders.of(this,
mViewModelFactory
).get(EpisodesViewModel::class.java)
mMainViewModel = ViewModelProviders.of(
this,
mViewModelFactory
).get(MainViewModel::class.java)
if (mBinding?.rv != null) {
mRV = mBinding?.rv
val context: Context? = mRV?.context
mRV?.setHasFixedSize(true)
mAdapter = EpisodesRecyclerViewAdapter(mMainViewModel)
mRV?.adapter = mAdapter
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
val dividerItemDecoration = DividerItemDecoration(
mRV?.context,
layoutManager.orientation
)
mRV?.addItemDecoration(dividerItemDecoration)
mRV?.layoutManager = layoutManager
}
mViewModel?.getMainFeed()
mViewModel?.mainFeed?.observe(viewLifecycleOwner, Observer {
mItems.addAll(it?.body()?.channel?.item!!)
Log.d(TAG, mItems.get(0).description)
mAdapter?.setItems(mItems)
mAdapter?.notifyDataSetChanged()
})
}
}
1 ответ
Попробуй использовать activity
собственность вместо this
в вашем EpisodesFragment
когда вы запрашиваете MainViewModel
:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mMainViewModel = ViewModelProviders.of(
activity,
mViewModelFactory
).get(MainViewModel::class.java)
// ...
}
ViewModelProviders.of
может вернуть разные MainViewModel
экземпляр для фрагмента.