【问题标题】:Unable to use lambda arrow expression for Livedata observe method in Kotlin无法在 Kotlin 中对 Livedata 观察方法使用 lambda 箭头表达式
【发布时间】:2019-06-14 21:59:48
【问题描述】:

我是 kotlin 的新手,在 LiveData 观察方法中使用 lambda 表达式时有点困惑。

observe方法的签名如下

observe(LifecycleOwner owner, Observer<? super T> observer)

其中 Observer 是具有单个方法的接口

void onChanged (T t)

但是,在 kotlin 中调用上述观察方法如下给出类型不匹配错误:

 val myViewModel = ViewModelProviders.of(this).get(AnimeListViewModel::class.java)

 myViewModel.animes.observe(this, { anime -> println(anime) })

这和在视图上调用 setOnClickListener 不一样吗?以下代码完美运行,没有任何编译错误:

val myView = View(this)

myView.setOnClickListener { view -> println(view) }

我已经阅读了this 答案,其中显示了如何使用 lambda 表达式(使用 SAM 转换)调用该方法。但是,我仍然不确定为什么简单的箭头表达式会失败。

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    LiveData 没有 lambda 表达式,您应该将观察者接口作为对象传递

    myViewModel.animes.observe(this, Observer { anime -> println(anime) })
    

    或者通过创建这样的扩展函数

    fun <T : Any> LiveData<T>.observe(lifecycleOwner: LifecycleOwner, block: (T) -> Unit) = observe(lifecycleOwner, Observer(block))
    

    这样称呼它

    myViewModel.animes.observe(this) { anime -> println(anime) }
    

    或者像这样

    fun main() {
       myViewModel.animes.observe(this, ::handleLiveData)
    }
    
    fun handleLiveData(anime: Anime) {
       println(anime)
    }
    

    【讨论】:

    • 在最新的 Kotlin 插件 1.3.40-release-Studio3.4-1 中存在一个缺陷,它使普通的 observe() 方法优先于扩展,因此它会自动认为它未使用并删除import(如果在您的 AS 上启用了自动导入)但编译器会抱怨。我猜这与他们最近推出的新型推理引擎有关。
    【解决方案2】:

    在 kotlin 上解决泛型有一些问题,所以这就是原因。 Kotlin 一直在做这个,你会找到完整的解释 here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多