You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin使用ViewBinding时如何通过字符串ID访问对应TextView

问题原因
  • ViewBinding的属性是编译期根据XML里的控件ID硬生成的,binding.xxx的xxx必须是编译阶段就确定的固定属性名,不会动态读取你代码里定义的同名变量值。你写binding.cellID时,编译器只会去GridmapBinding类里找名为cellID的属性,不会读取你定义的字符串变量cellID的内容,自然会报未解析引用错误。
  • 额外代码问题:你当前导入的是android.R(系统资源类),会导致后续引用自己项目的颜色、ID资源时匹配错误,需要删掉这个导入,改为导入你自己项目包下的R类。
高性能实现方案

不要使用Resources.getIdentifier(),该方法每次调用都会走资源表反射查找,高频调用性能损耗明显。针对网格场景最高效的方案是一次性初始化视图映射表,后续访问为O(1)复杂度,无任何反射开销:

  1. 选择安卓平台优化过的SparseArray作为映射存储结构(比HashMap更省内存、整数key存取效率更高),在Activity里定义存储容器:
    private val cellViews = SparseArray<TextView>()
    
  2. 在onCreate完成视图绑定后,仅执行一次初始化,把所有网格的TextView控件和对应的资源ID存入映射表:
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: GridmapBinding = GridmapBinding.inflate(layoutInflater)
        setContentView(binding.root)
    
        // 初始化视图映射,仅执行一次
        cellViews.put(R.id.cell1, binding.cell1)
        cellViews.put(R.id.cell2, binding.cell2)
        // 其余cell按同样方式存入,如果是动态addView生成的网格,创建TextView时直接存入即可,无需手写全量ID
    }
    
  3. 后续操作控件时,直接用资源ID(Int类型,比字符串存取效率更高)作为key从映射表取控件即可,切换操作对象只需要修改ID变量的值:
    // 存储当前要操作的cell ID
    var currentCellId = R.id.cell1
    // O(1)复杂度直接取到控件,无额外开销
    cellViews[currentCellId]?.setBackgroundResource(R.color.teal_200)
    
    // 切换操作其他cell
    currentCellId = R.id.cell2
    cellViews[currentCellId]?.text = "更新内容"
    

如果你确实需要用字符串作为key切换控件,只需要把存储结构换成HashMap<String, TextView>,初始化时把字符串ID作为key存入即可,存取同样是O(1)复杂度,性能远高于反射方案:

private val cellViewStrMap = HashMap<String, TextView>()

// 初始化时
cellViewStrMap["cell1"] = binding.cell1

// 使用时
var cellID = "cell1"
cellViewStrMap[cellID]?.setBackgroundResource(R.color.teal_200)

该方案哪怕面对上千个网格单元的规模,也不会有可感知的性能损耗,完全规避了getIdentifier的反射开销问题。

内容的提问来源于stack exchange,提问作者Ellis Svannish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 02:57:08