如何在Kotlin中在绑定操作中使用变量?

huangapple go评论50阅读模式
英文:

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) }

// 访问图片
images
0
+
网站访问量
.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
images
0
+
网站访问量
.setImageBitmap(scaledBitmap)

There are other ways to build that collection instead of listing them explicitly - you could use theContainingLayout.children.filterIsInstance&lt;ImageView&gt; to pull out all the ImageViews 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 ImageViews), and then use those:

val images = List(imageCount) { &quot;crimePhoto{it + 1}&quot; }
    .map { name -&gt; resources.getIdentifier(name, packageName) }
    .mapNotNull { id -&gt; findViewById&lt;ImageView&gt;(id) }

(I'm doing this by memory so I'm not sure if you need to explicitly cast to List&lt;ImageView&gt; 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

huangapple
  • 本文由 发表于 2023年2月24日 07:55:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75551449.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定