英文:
How to use a variable in a bind operation in Kotlin?
问题
这似乎是一个非常简单的问题,但我似乎无法弄清楚。
我有一个使用Kotlin进行绑定操作... 例如,
binding.crimePhoto1.setImageBitmap(scaledBitmap)
我希望“1”实际上是一个引用正在更改的计数器的变量。我似乎无法在Kotlin中得到正确的语法。我已经在进行绑定的同一类中设置了这个变量。
例如:
var counter: Int = 1
...
binding.crimePhoto$counter.setImageBitmap(scaledBitmap) <---不起作用
...
binding.crimePhoto{$counter}.setImageBitmap(scaledBitmap) <---不起作用
...
binding.crimePhoto{counter}.setImageBitmap(scaledBitmap) <---看起来会起作用,但我会得到一个错误(未解析的引用:crimePhoto)
我尝试过上述各种排列组合。我尝试将其设置为类变量和函数内部的变量。
英文:
This seems like a very simple question but I can't seem to figure it out.
I have a bind operation using Kotlin ... for instance,
binding.crimePhoto1.setImageBitmap(scaledBitmap)
I want the "1" to actually be variable that references a changing counter. I can't seem to get the syntax right in Kotlin. I have set the variable within the same class where the binding is happening.
For instance:
var counter: Int = 1
...
binding.crimePhoto$counter.setImageBitmap(scaledBitmap) <---does not work
...
binding.crimePhoto{$counter}.setImageBitmap(scaledBitmap) <---does not work
...
binding.crimePhoto{counter}.setImageBitmap(scaledBitmap) <---look like it'll work but I get an error (Unresolved reference: crimePhoto)
I've tried the above permutations. I've tried setting it as a class variable and a variable within the function itself.
答案1
得分: 1
你不能这样做。binding.crimePhoto1
只是一个名为 binding
的对象上的一个变量,在 Kotlin 中,除了通过反射操作之外,你不能像这样引用变量 - 你必须使用它们的显式名称。
这种情况的典型做法是创建一个包含你要处理的项目的集合,然后使用你的可变值引用该集合的*成员。类似于这样:
val images = listOf(
binding.crimePhoto1, binding.crimePhoto2
)
// 或者更简洁的方式,这样你只需引用 binding 一次
val images = binding.run { listOf(crimePhoto1, crimePhoto2) }
// 访问图片
images0+网站访问量.setImageBitmap(scaledBitmap)
除了显式列出它们以外,还有其他构建该集合的方法 - 你可以使用 theContainingLayout.children.filterIsInstance<ImageView>
来提取布局的顶层中的所有 ImageView
(如果它们嵌套在其他布局中,则需要递归函数)。
或者,你可以跳过视图绑定,生成一个视图ID列表(类似于你尝试做的),然后使用 findViewById
查找它们(创建一个新的 ImageView
列表),然后使用它们:
val images = List(imageCount) { "crimePhoto${it + 1}" }
.map { name -> resources.getIdentifier(name, packageName) }
.mapNotNull { id -> findViewById<ImageView>(id) }
(我是根据记忆编写的,所以我不确定是否需要在这种情况下显式转换为 List<ImageView>
- 如果需要的话,你可以使用 filterIsInstance
,让它处理 null 值)
拥有这样的集合的另一个好处是你有一个明确定义的元素集合 - 因此,你可以迭代它们来设置点击监听器,使用集合大小来设置 counter
的边界等。
英文:
You can't do that kind of thing. binding.crimePhoto1
is just a variable on an object called binding
, and outside of reflection shenanigans you can't refer to variables in Kotlin like that - you have to use their explicit name.
The typical way to do this kind of thing would be to create a collection of the items you're working with, and then refer to members of that collection with your changing value. Something like this:
val images = listOf(
binding.crimePhoto1, binding.crimePhoto2
)
// or for shorthand, so you refer to binding once
val images = binding.run { listOf(crimePhoto1, crimePhoto2) }
// access the images
images0+网站访问量.setImageBitmap(scaledBitmap)
There are other ways to build that collection instead of listing them explicitly - you could use theContainingLayout.children.filterIsInstance<ImageView>
to pull out all the ImageView
s at the top level of a layout (you'll need a recursive function if they're nested inside other layouts).
Or you could skip view binding, and generate a list of view IDs (similar to what you're trying to do), look them up with findViewById
(creating a new list of ImageView
s), and then use those:
val images = List(imageCount) { "crimePhoto{it + 1}" }
.map { name -> resources.getIdentifier(name, packageName) }
.mapNotNull { id -> findViewById<ImageView>(id) }
(I'm doing this by memory so I'm not sure if you need to explicitly cast to List<ImageView>
in this situation - you could use filterIsInstance
if you need to, and let that handle the nulls too)
The other nice thing about having a collection like this is you have a clearly defined set of elements - so you can iterate over them to set click listeners, use the collection size to set the bounds of counter
, etc
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论