【发布时间】:2020-11-21 14:05:22
【问题描述】:
在 Kotlin 基础课程中,我们有以下代码:
@BindingAdapter("sleepImage")
fun ImageView.setSleepImage(item: SleepNight?) {
item?.let {
setImageResource(when (item.sleepQuality) {
0 -> R.drawable.ic_sleep_0
1 -> R.drawable.ic_sleep_1
2 -> R.drawable.ic_sleep_2
3 -> R.drawable.ic_sleep_3
4 -> R.drawable.ic_sleep_4
5 -> R.drawable.ic_sleep_5
else -> R.drawable.ic_sleep_active
})
}
}
在其他语言中,我会通过使用 sleepQuality 整数来查找匹配元素来简化这一点,例如在 Typescript 中:
setImageResource(R.drawable[`ic_sleep_${item.sleepQuality}`] ?? R.drawable.ic_sleep_active)
要开始尝试这个,即使我的第一步没有编译:
0 -> R.drawable["ic_sleep_0"] // doesn't compile
这种操作在 Kotlin 中是否可行?
编辑/更新
这里有一些很好的回应。
对于这个特定的用例,我可以按字符串查找资源,类似于我正在尝试的:
val resId = context.resources.getIdentifier("ic_sleep_${item.sleepQuality}", "drawable", context.packageName)
但是,这不是一个通用的解决方案。以下方法不起作用:
val x = item['sleepQuality']
正如某些回复中所指出的,这可以通过反射来实现。这将如何实现?
【问题讨论】:
-
嗨,有趣,也许用reflection
-
我不知道您在这里使用的对象,但有没有一种方法可以使用数组或列表——类型 设计 用于索引访问——而不是一系列单独的属性?
-
@gidds 是的,这个例子,被编号,作为一个数组会更好(你能有一个资源数组吗?)但我的问题,一般来说,仍然存在。
-
我不确定该代码来自哪里,或者它是否是为了展示开关而编写的,但我只是指出使用固定的 @ 会更干净987654328@ 并修改其级别。通过字符串使用反射或
getIdentifier的解决方案不提供编译时安全性,因此通常应避免使用它们。 -
resources.getIdentifier在后台使用反射。请注意,应该避免使用反射,因为它放弃了使用强类型语言的好处(编译器甚至在您运行代码之前就捕获了您的错误)。如果您首先将可绘制对象存储在数组中,则不需要此when语句。
标签: kotlin