Java/Kotlin 回调语法 - 转换为 Kotlin 后我真的需要 2 个回调定义吗?



我有一个问题,几天来一直挑战着我,但没有解决方案(更直接地说,没有我认为正确的解决方案(。问题在于回调,Java实现与Kotlin实现

我有这个Java方法:

public void setOnSelectionChange(MapControlUpdate mapMenuControl) {
this.mapControlUpdate = mapMenuControl;
}
private MapControlUpdate mapControlUpdate;
public interface MapControlUpdate {
void onSelectionChange(MAP_TYPE mapType);
}

使用上面的实现,我在 Java 和 Kotlin 中都有我想要的东西(下面(。

Java(之前(:

widgetMapType.setOnSelectionChange(mapType -> {
Toast.makeText(getContext(), "clicked: " + mapType, Toast.LENGTH_LONG).show();
});

Kotlin (之前(:

widgetMapType.setOnSelectionChange {
Toast.makeText(context, "clicked: $it", Toast.LENGTH_LONG).show()
}

转换后的新 Kotlin 代码为:

fun setOnSelectionChange(mapMenuControl: MapControlUpdate?) {
mapControlUpdate = mapMenuControl
}
private var mapControlUpdate: MapControlUpdate? = null

转换为 Kotlin 后,Java 用法保持不变,但我需要按如下方式更改 Kotlin 代码,否则出现语法错误:

Kotlin (之后(:

widgetMapType.setMapMenuControl(object: WidgetMapType.MapControlUpdate {
override fun onSelectionChange(mapType: WidgetMapType.MAP_TYPE?) {
Toast.makeText(context, "clicked: $mapType", Toast.LENGTH_LONG).show()
}
})

为了回到我想去的地方,我发现唯一的解决方案似乎是实现 2 个回调;1 个允许 Java 使用原始语法,另一个允许 Kotlin 语法保持不变。

这是我正在使用的代码(它有效(:

var onSelectionChange: MapControlUpdate? = null
private var onSelectionChangeListener: ((MapDisplayTypes?) -> Unit)? = null
fun setOnSelectionChange(listener: (MapDisplayTypes?) -> Unit){
onSelectionChangeListener = listener
}

我根据需要触发两个回调

onSelectionChange?.onSelectionChange(it)    // Java
onSelectionChangeListener?.invoke(it)   // Kotlin

我真的不敢相信没有更正确的方法,但我的搜索(在这里和网络上(返回了大量 Kotlin 和 Java 的示例,但它们都与我上面基于代码的示例一致(也如上所示(。 我怀疑可能有注释或我缺少的东西,所以找不到其他解决方案,我在这里求助于社区。

提前谢谢你!!

我怀疑你只需要在Java中保留你的interface MapControlUpdate定义。

而不是两个回调,你只保留一个回调并根据需要进行转换:

var onSelectionChange: MapControlUpdate? = null
fun setOnSelectionChange(listener: (WidgetMapType.MAP_TYPE?) -> Unit){
onSelectionChangeListener = object : MapControlUpdate {
override fun onSelectionChange(mapType: WidgetMapType.MAP_TYPE?) {
listener(mapType)
}
}
}

或者,如果多次使用MapControlUpdate则编写帮助程序函数。

但真正的解决方案是,正如 karmakaze 所说:将接口保留在 Java 中,直到 Kotlin 1.4 然后声明为fun interface.

最新更新