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

如何移除代码动态创建的TextView?ConstraintLayout下清除无效问题

解决ConstraintLayout旧视图未移除的问题

你当前代码里用ConstraintSet.clear(v.id)只是清除了视图的约束关系,并没有从父布局中移除视图本身,所以旧视图会一直留在屏幕上,新视图叠加上去就会出现覆盖的情况。

正确的做法是直接从父布局中移除所有旧子视图,替换掉原来的约束清除逻辑:

private fun generateView(tirage:CharArray) {
    val set = ConstraintSet()
    val parentLayout = binding.reglette
    var i = 0

    // 替换原来的ConstraintSet.clear逻辑:直接移除所有子视图
    for (v in parentLayout.children.toList()) { // 转成List避免遍历中修改集合的问题
        parentLayout.removeView(v)
    }

    listLettre.clear()

    // 以下原有逻辑保持不变
    val dummyLeft = TextView(requireActivity())
    listLettre.add(dummyLeft)
    listPos.add(i)
    listIndex.add(i++)

    for (lettre in tirage) {
        val childView = TextView(requireActivity())
        childView.id = View.generateViewId()
        childView.width = LARGEUR_LETTRE.toInt()
        childView.height = LARGEUR_LETTRE.toInt()
        childView.setBackgroundResource(R.drawable.lettre)
        childView.gravity = Gravity.CENTER
        childView.text = lettre.toString()
        childView.textSize = 34f
        childView.setTypeface(null, Typeface.BOLD)
        parentLayout.addView(childView, i - 1)
        listLettre.add(childView)
        listPos.add(i)
        listIndex.add(i++)
    }

    val dummyRight = TextView(requireActivity())
    listLettre.add(dummyRight)
    listPos.add(i)
    listIndex.add(i)

    val premL = listLettre.drop(1).first()

    val pad = (parentLayout.width - (tirage.size * LARGEUR_LETTRE.toInt())) / 2

    set.clone(parentLayout)
    set.connect(
        premL.id,
        ConstraintSet.START,
        ConstraintSet.PARENT_ID,
        ConstraintSet.START,
        pad
    )

    val windowedList = listLettre.drop(1).dropLast(1).windowed(2, 1, false)

    for (pair in windowedList)
        set.connect(
            pair.last().id,
            ConstraintSet.START,
            pair.first().id,
            ConstraintSet.END
        )

    set.applyTo(parentLayout)
}

补充说明

  • 遍历子视图时要转成toList(),因为直接遍历parentLayout.children(这是一个动态集合)时,移除元素会导致集合结构变化,引发遍历异常。
  • 如果你的listLettre里保存的是之前的旧视图,调用listLettre.clear()已经能清空列表,但关键还是要从父布局中移除视图实体,否则它们会一直占据布局空间。

内容的提问来源于stack exchange,提问作者Simon W

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:58:21