フラグメントTabBarActivity
をホストするアクティビティEquipmentRecyclerViewFragment
があります。フラグメントはLiveDataコールバックを受け取りますが、アクティビティは受け取りません(デバッグモードのブレークポイントで証明されています)。奇妙なのは、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
}
EquipmentViewModel
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のみを監視するようにアクティビティを変更しました。
アクティビティと同じようにViewModelのリファレンスを取得するには、同じアクティビティを渡す必要があります。ViewModelProviders.of(getActivity)
を使用する必要があります。this
を渡すと、ViewModelの新しいインスタンスを受け取ります。
詳細情報 フラグメント間でデータを共有