观察者onChanged从未打过电话

时间:2017-06-14 07:43:23

标签: android kotlin

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
}

mViewModel已确认更改。但是观察者onChanged从未被调用过。

问题:为什么它不起作用?

修改 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

为了提及,getBar已经返回LiveData

fun getBar(): LiveData<List<String>> = mBar

onChange仍然不会触发。

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

3 个答案:

答案 0 :(得分:4)

类型List没有观察方法 ViewModel与观察无关,它主要是通过配置更改持续存在的状态。

对于可观察数据,您需要(Mutable)LiveData个对象。这些是生命周期感知并管理其数据的观察者。

请参阅代码示例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"))
    }
}

答案 1 :(得分:2)

好的,所以我找到了答案。

如果您要扩展AppCompatActivity并希望使用LiveData,则必须实施LifecycleRegistryOwner接口及其唯一方法 - getLifecycle

问题在于:

override fun getLifecycle(): LifecycleRegistry {
  return LifecycleRegistry(this)
}

必须:

val mLifecycleRegistry = LifecycleRegistry(this)
..
override fun getLifecycle(): LifecycleRegistry {
  return mLifecycleRegistry
}

答案 2 :(得分:2)

问题是,当您调用LiveData方法时,它会将mBar的新实例重新分配到mBar。并且您已将观察者分配给init的上一个实例,因为您在调用 mViewModel.getBar().observe(this, Observer<List<String>> { override fun onChanged(bar: List<String>) { // Never triggered } }) 方法之后:

mBar

要解决此问题,只需使用MutableLiveData初始化mBar,然后更改其值(不要将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 } 重新分配给另一个实例)。

检查以下代码:

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Destination.class), 0);