Reputation: 336
I'm trying to save an "Episode" in my MainViewModel
and allow other Fragments
to have access to it via that ViewModel
.
In MainActivity
I'm observing changes in the ViewModel
, which is never being triggered. Weirdly, it works fine for my MainFeed RSS object
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")
})
}
Here's the 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
}
}
In my EpisodesFragment
I'm passing MainViewModel
to a RecyclerView
adapter. In the layout for the Episode item I have an onClick()
that calls mViewModel.setEpisode(episode)
So the clicks are registering. I set breakpoints and can see the episode item is actually there and holds data in the setEpisode()
method. It just never actually gets set in the LiveData
. I verified that the ViewModel
is not null in any locations I've used it.
Edit: Adding code for 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()
})
}
}
Upvotes: 1
Views: 610
Reputation: 30715
Try to use activity
property instead of this
in your EpisodesFragment
when you are requesting MainViewModel
:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mMainViewModel = ViewModelProviders.of(
activity,
mViewModelFactory
).get(MainViewModel::class.java)
// ...
}
ViewModelProviders.of
may return different MainViewModel
instance for fragment.
Upvotes: 2