viewModel.gardenPlantings.observe(viewLifecycleOwner, Observer { plantings ->
binding.hasPlantings = (plantings != null && plantings.isNotEmpty())
})
这个 Observer 是什么写法呢?真搞不懂,kotlin 感觉太天马行空了,来个大神指教一下,谢谢
1
jinksw 2018-12-24 13:44:34 +08:00
只有一个函数声明的接口可以用 Lambda 代替?
类似 setOnClickListener{ view->xxx } |
3
Mystery0 2018-12-24 14:01:54 +08:00 via Android
Observer 是一个接口,这个接口里面只有一个函数,所以可以简写成这样
|
4
Mystery0 2018-12-24 14:02:24 +08:00 via Android
其实看一下 Observer 的定义应该就清楚了
|
6
abbenyyy OP @Mystery0 那为何
``` val livePlantList = Transformations.switchMap(growZoneNumber) { if (it == NO_GROW_ZONE) { plantRepository.getPlants() } else { plantRepository.getPlantsWithGrowZoneNumber(it) } } ``` [源码出处]( https://github.com/googlesamples/android-sunflower/blob/a85cd9b49a924ee2ad029685225d6d071de6bd15/app/src/main/java/com/google/samples/apps/sunflower/viewmodels/PlantListViewModel.kt#L41) Transformations.switchMap 第二个参数也是接口,Transformations.switchMap 的最后一个 lambda 表达式参数移出括号外的方式,并不能套用在 Observer 上面,也就是 ``` viewModel.gardenPlantings.observe(viewLifecycleOwner) { plantings -> binding.hasPlantings = (plantings != null && plantings.isNotEmpty()) } ``` 这个写法并不能编译通过 |
7
abbenyyy OP @jinksw 如同我上面说的,如果函数最后一个参数是 lambda 表达式可移出括号外,但是 Observer 如果这样写,编译并不能通过。所以我搞不懂为何有这两种方式
|
8
loshine1992 2018-12-24 14:17:33 +08:00
从这个简化的
```kotlin viewModel.gardenPlantings.observe(viewLifecycleOwner, object : Observer { override fun 方法名(plantings: 参数类型) { binding.hasPlantings = (plantings != null && plantings.isNotEmpty()) } }) ``` 最简化的写法是这样 ```kotlin viewModel.gardenPlantings.observe(viewLifecycleOwner) { binding.hasPlantings = (it!= null && it.isNotEmpty()) } ``` |
9
jinksw 2018-12-24 14:22:33 +08:00
@loshine1992 然而楼主说这样不行
🤔 到底是为啥呢 是不是最后一个参数 是泛型类 的缘故 |
10
holmesabc 2018-12-24 14:23:04 +08:00
Observer 是个 java 里面的单方法 接口。就能简写
|
11
abbenyyy OP @loshine1992 你可以 clone 下来谷歌的 android-sunflower 项目,按照你的方式改写一下,并不能编译通过,我已经试过了
|
12
jinksw 2018-12-24 14:32:23 +08:00
|
13
loshine1992 2018-12-24 14:36:32 +08:00
@abbenyyy #2 这个情况下大概率有另外一个方法也接受一个接口的参数,
observe(viewLifecycleOwner: A 参数, observer: Observer) observe(viewLifecycleOwner: A 参数, subscriber: Subscriber) 此时需要区分,不能直接用 lambda |
14
jinksw 2018-12-24 14:42:20 +08:00
感觉应该是编译器的锅 我看那个 observer 方法也没有重载
|
16
dagger2 2018-12-24 16:56:50 +08:00
viewModel.gardenPlantings.observe 是个 java 方法,接收的参数是一个 Observer 的实现,而不是() -> Unit
|
17
pipicat 2018-12-24 17:26:10 +08:00
应该跟泛型有关系。
|
18
pipicat 2018-12-24 17:33:28 +08:00
val a = object : View.OnClickListener {
override fun onClick(v: View?) { } } val b = object : Observer<Any>{ override fun onChanged(t: Any?) { } } idea 提示后简化成 val a = View.OnClickListener { } val b = Observer<Any> { } 这里 observer 不加泛型是无法单独声明的。 而 livedata 的这个方法泛型已经确定了,所以 viewModel.gardenPlantings.observe(viewLifecycleOwner, Observer { plantings -> binding.hasPlantings = (plantings != null && plantings.isNotEmpty()) }) 上的泛型没有显式的写出来。 |
19
pipicat 2018-12-24 17:45:33 +08:00
测试了一下 java8 的代码。同样的代码,java8 不用显式写 Observer,但是参数要写出来。
|
20
SoloCompany 2018-12-26 23:12:43 +08:00 via iPad
java8 的 function interface 和一 kotlin,的 KFunction 并不是同一种类型,需要显式转换,所以需要显式构造 Observer 接口
java8 code 则是类型推断系统自动把 lambda 转换为推断出来的 function interface 也就是说 observer,不需要通过显式的类型转换 |