FooActivity.kt:
class FooActivity : AppCompatActivity(), LifecycleRegistryOwner {
override fun getLifecycle(): LifecycleRegistry {
return LifecycleRegistry(this)
}
..
// <-- here mViewModel is null
mViewModel.getBar().observe(this, Observer<List<String>> {
override fun onChanged(bar: List<String>) {
// Never triggered
}
})
mViewModel.init()
// <-- here mViewModel has changed
}
The mViewModel is confirmed to change. However the observer's onChanged is never called.
Question: why doesn't it work?
Edit: FooViewModel.kt:
class FooViewModel(application: Application) : AndroidViewModel(application) {
val baz: BazPagerAdapter? = null
..
fun init(fm: FragmentManager) {
mBar = listOf("1", "2", "3")
}
..
fun getBar(): List<String> = mBar
..
fun setBaz(pager: ViewPager, periods: List<BazFragment>) {
pager.adapter = BazPagerAdapter(mFragmentManager!!, periods)
}
}
Edit2:
For got to mentiond, getBar already returns LiveData
fun getBar(): LiveData<List<String>> = mBar
And the onChange still wouldn't trigger.
Edit3:
class FooViewModel(application: Application) : AndroidViewModel(application) {
private var mBar: MutableLiveData<List<String>>? = null
..
fun init(fragmentManager: FragmentManager) {
..
if (mBar == null) {
mBar = MutableLiveData<List<String>>()
}
mBar?.value = periods
}
..
fun getBar(): LiveData<List<String>>? = mBar
There is no observe method for type List.
The ViewModel has nothing to do with observing either, it is there mainly to have state that persists through configuration changes.
For observable data you want (Mutable)LiveData objects. These are lifecycle aware and manage observers for their data.
Please see the code examples here:
public class MyViewModel : ViewModel() {
private val mBar = MutableLiveData<List<String>>()
fun getBar(): LiveData<List<String>> = mBar
fun init() {
mBar.setValue(listOf("1", "2", "3"))
}
}
So the problem is when you call init method, it reassigns new instance of LiveData into mBar. And you have assigned observer to previous instance of mBar because you are calling init method after :
mViewModel.getBar().observe(this, Observer<List<String>> {
override fun onChanged(bar: List<String>) {
// Never triggered
}
})
To solve the problem just initialise mBar with MutableLiveData and then change its value (Do not re-assign mBar with another instance).
Check following code:
class FooViewModel(application: Application) : AndroidViewModel(application) {
private var mBar: MutableLiveData<List<String>> = MutableLiveData()
fun init(fragmentManager: FragmentManager) {
mBar.value = periods // Changing value only, not new instance
}
fun getBar(): LiveData<List<String>> = mBar
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With