繁体   English   中英

Kotlin 使用字符串提供的 ID 更改 ViewText

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM