有一个类实现多个观察者

时间:2018-07-07 20:31:31

标签: android android-livedata

我实现了一个最初实现android.arch.lifecycle.Observer的Fragment,我想开始观察其他一些实时数据,但不能。我从这里开始:

class MyFragment : BaseFragment(), Observer<FragmentData> {
  lateinit var viewModel: MyViewModel

  override fun onActivityCreated(savedInstanceState: Bundle?) {
    viewModel.fragmentData.observe(this, this)
  }

  override fun onChanged(data: FragmentData?) {
    activity?.title = getTitleFromData(data)
  }
}

如果我将类更新为包含其他可观察的数据,例如:

class MyFragment : BaseFragment(), Observer<FragmentData>, Observer<OtherData> {
  lateinit var viewModel: MyViewModel

  override fun onActivityCreated(savedInstanceState: Bundle?) {
    viewModel.fragmentData.observe(this, this)
  }

  override fun onChanged(otherData: OtherData) {
    // update UI from otherData
  }

  override fun onChanged(data: FragmentData?) {
    activity?.title = getTitleFromData(data)
  }
}

我得到一个错误:

  

“ Observer”的类型参数T的值不一致:   FragmentData,OtherData   超型出现两次

我希望对理解为什么编译器无法辨别类型之间的差异并想知道最佳替代模式有帮助。

是这样吗?

viewModel.fragmentData.observe(this, fragmentDataObserver)

private val fragmentDataObserver = Observer<Fragmentdata> {
   activity?.title = getTitleFromData(it)
}

2 个答案:

答案 0 :(得分:0)

由于类型擦除,编译器无法识别类型之间的差异。程序编译时,几乎所有通用信息都将从类中剥离。不再有Observer<FragmentData>Observer<OtherData>,只有一个Observer类。现在,无需进行类型擦除,就可以实现这样的事情

class MyFragment : BaseFragment(), Observer<FragmentData>, Observer<OtherData> {
   override fun onChanged(otherData: OtherData) {
      // update UI from otherData
    }

    override fun onChanged(data: FragmentData?) {
      activity?.title = getTitleFromData(data)
    }
}

,但是一旦您应用类型擦除,则基本上是在尝试将同一类扩展两次,并为同一基本方法提供两个不同的覆盖方法,这是不允许的。这就是为什么编译器不允许您这样做。我会以有限的知识给出准确的描述。

作为替代方案,如建议的注释一样,请尝试使用lambda而不是使片段本身成为双重观察者。

class MyFragment : BaseFragment(), Observer<OtherData> {
    lateinit var viewModel: MyViewModel

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel.fragmentData.observe(this, Observer { onChanged(it) })
    }

    override fun onChanged(otherData: OtherData?) {
        // update UI from otherData
    }

    private fun onChanged(data: FragmentData?) {
        activity?.title = getTitleFromData(data)
    }
}

答案 1 :(得分:0)

您可以尝试实现以下通用观察者接口:

class MyFragment : BaseFragment(), Observer<Any> {...} 

然后在onChanged方法上使用

override fun onChanged(any: Any?) {
    when:
    any is isOtherData -> Do OtherData things
    any is FragmentData -> Do FragmentData things
}

第二种解决方法是使OtherData和FragmentData成为父类,FatherInterface只是体内没有任何东西的接口:

interface OtherData: FatherInterface{}...
interface FragmentData : FatherInterface{}...

那你就可以做

class MyFragment : BaseFragment(), Observer<FatherInterface>{}...

override fun onChanged(fatherInterface: FatherInterface?) {
    when{
        fatherInterface is OtherData -> ...
        fatherInterface is FragmentData -> ...
    }
    // update UI from otherData
}