[英]Kotlin Change ViewText with an ID provided by a String
目标:使用可变字符串从活动中获取 ViewText 资源并对其进行编辑(因为可以更改字符串以更改同一函数中的其他 ViewText)。
上下文:我正在使用 TableRows 和 TextViews 制作一个网格,可以将其更改为一种可以从数组生成的 map。
问题:绑定命令无法识别字符串。 请参阅我的评论“这里的问题”。
试过: getResources.getIdentifier 但有人告诉我这会大大降低性能。
摘自 gridmap.xml
<TextView
android:id="@+id/cell1"/>
网格图.kt
package com.example.arandomadventure
import android.R
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.arandomadventure.databinding.GridmapBinding
class GridMap : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//sets the binding and assigns it to view
val binding: GridmapBinding = GridmapBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
//creates a string variable
var cellID = "cell1"
//uses binding to set the background colour to teal
binding.cellID.setBackgroundResource(R.color.teal_200) //<- PROBLEM HERE (Unresolved Reference)
//getResources.getIdentifier is not an option as it degrades performance on a larger scale
}
}
绑定 object 只是一个自动生成的 class,其 class 成员由布局中的视图定义 Z3501BB093D393810B67105ED 您不能使用您显示的语法添加或访问 class 上的字段 - 绑定类与任何其他 class 没有区别。 如果您希望能够按名称访问它们,可以将它们加载到 map
val viewMap = mapOf(
"cell1" to binding.cell1,
"cell2" to binding.cell2,
"cell3" to binding.cell3
)
然后您可以使用 map 按名称访问它们
var cellID = "cell1"
viewMap[cellID].setBackgroundResource(R.color.teal_200)
如果您希望 map 成为 class 成员,您可以这样设置
private lateinit var viewMap: Map<String,View>
override fun onCreate(savedInstanceState: Bundle?) {
//...
viewMap = mapOf(
"cell1" to binding.cell1,
"cell2" to binding.cell2,
"cell3" to binding.cell3
)
}
如果您的布局有数百个视图并且这变得很麻烦,您可能需要考虑以编程方式添加视图。
编辑
如果您想以更丑陋但更自动的方式执行此操作,则可以使用反射。 为此,您需要添加此 gradle 依赖项:
implementation "org.jetbrains.kotlin:kotlin-reflect:1.7.0"
然后您可以使用绑定中的所有视图以编程方式构建 map。
val viewMap = mutableMapOf<String,View>()
GridmapBinding::class.members.forEach {
try {
val view = it.call(binding) as? View
view?.let { v ->
viewMap[it.name] = v
}
}
catch(e: Exception) {
// skip things that can't be called
}
}
或者您可以使用它来调用方法(请记住,如果不存在这样的 class 成员,则会抛出该方法):
var cellID = "cell1"
val view = GridmapBinding::class.members.filter { it.name == cellID }[0].call(binding)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.