【发布时间】:2018-07-22 17:32:23
【问题描述】:
我有一个活动,TabBarActivity,它承载了一个片段,EquipmentRecyclerViewFragment。片段接收 LiveData 回调,但 Activity 没有(如调试模式下的断点所证明的那样)。奇怪的是,如果我调用 ViewModel 的 initData 方法,Activity 回调确实会触发。以下是上述组件的相关部分:
TabBarActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initVM()
setContentView(R.layout.activity_nav)
val equipmentRecyclerViewFragment = EquipmentRecyclerViewFragment()
supportFragmentManager
.beginTransaction()
.replace(R.id.frameLayout, equipmentRecyclerViewFragment, equipmentRecyclerViewFragment.TAG)
.commit()
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}
var eVM : EquipmentViewModel? = null
private fun initVM() {
eVM = ViewModelProviders.of(this).get(EquipmentViewModel::class.java)
eVM?.let { lifecycle.addObserver(it) } //Add ViewModel as an observer of this fragment's lifecycle
eVM?.equipment?.observe(this, loadingObserver)// eVM?.initData() //TODO: Not calling this causes Activity to never receive the observed ∆
}
val loadingObserver = Observer<List<Gun>> { equipment ->
...}
EquipmentRecyclerViewFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
columnCount = 2
initVM()
}
//MARK: ViewModel Methods
var eVM : EquipmentViewModel? = null
private fun initVM() {
eVM = ViewModelProviders.of(this).get(EquipmentViewModel::class.java)
eVM?.let { lifecycle.addObserver(it) } //Add ViewModel as an observer of this fragment's lifecycle
eVM?.equipment?.observe(this, equipmentObserver)
eVM?.initData()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_equipment_list, container, false)
if (view is RecyclerView) { // Set the adapter
val context = view.getContext()
view.layoutManager = GridLayoutManager(context, columnCount)
view.adapter = adapter
}
return view
}
设备视图模型
class EquipmentViewModel(application: Application) : AndroidViewModel(application), LifecycleObserver {
var equipment = MutableLiveData<List<Gun>>()
var isLoading = MutableLiveData<Boolean>()
fun initData() {
isLoading.setValue(true)
thread { Thread.sleep(5000) //Simulates async network call
var gunList = ArrayList<Gun>()
for (i in 0..100){
gunList.add(Gun("Gun "+i.toString()))
}
equipment.postValue(gunList)
isLoading.postValue(false)
}
}
最终目标是让活动只观察 isLoading MutableLiveData 布尔值,但由于这不起作用,我将活动更改为只观察设备 LiveData 以最大限度地减少变量的数量。
【问题讨论】:
-
尝试在片段中传递 ViewModelProviders.of(getActivity) 而不是“this”
-
做到了!我将我的片段
initVM()代码更改为val myActivity = activity ?: return eVM = ViewModelProviders.of(myActivity).get(EquipmentViewModel::class.java),它触发了两者。如果您能解释为什么它在答案中起作用,我会将其标记为已接受并支持。 -
使用
viewLifecycleOwner怎么样?
标签: android android-fragments mvvm kotlin android-livedata