【发布时间】:2019-06-10 23:44:26
【问题描述】:
我正在尝试在我的 MainViewModel 中保存一个“剧集”,并允许其他 Fragments 通过该 ViewModel 访问它。
在MainActivity 中,我正在观察ViewModel 的变化,它从未被触发。奇怪的是,它适用于我的 MainFeed RSS 对象
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()
})
}
}
【问题讨论】:
-
我猜你可以在这里完成问号
mViewModel?,bczViewModelProviders.of()将始终返回ViewModel -
GlobalScope.launch不推荐使用,应该使用本地范围来启动协程。 -
能否提供
EpisodesFragment的代码 -
好的,我会编辑的。
标签: android mvvm kotlin android-livedata