【问题标题】:How to get parent ConstraintLayout view to match its child TextView height programmatically如何以编程方式获取父 ConstraintLayout 视图以匹配其子 TextView 高度
【发布时间】:2026-02-19 06:45:01
【问题描述】:

学习 ConstraintLayout 和 Kotlin 真是太棒了。我有一个constraintLayout popupView,它是TextView titleLabel 的父视图。我希望 popupView 高度调整到其子 titleLabel TextView 的内容。由于使用的文本字符串不同,titleLabel 的高度会有所不同。

titleLabel 和 popupView 都为高度布局参数设置为 WRAP_CONTENT,但 popupView 没有得到渲染。给popupView的constraintSet添加固定高度约束会渲染,但是titleLabel高度变化时固定高度不起作用。

任何想法如何让它工作?这就是我所拥有的

open class PopupActivity(): AppCompatActivity() {

  public var message:String = "This is a message string for the label"

  val titleLabel: TextView by lazy {
    val label = TextView(this)
    label.gravity = Gravity.CENTER
    label.setTextSize(Constants.FontSizePopupTitle)
    return@lazy label
  }

  val popupView: ConstraintLayout by lazy {
    val view = ConstraintLayout(this)
    view.setBackgroundColor(Color.primary())
    return@lazy view
  }

  val view: ConstraintLayout by lazy {
    val v = ConstraintLayout(this)
    return@lazy v
  }

  @SuppressLint("ResourceType")
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    view.id = 1
    popupView.id = 2
    titleLabel.id = 5

    var margin = 2 * Constants.SpacingStandard.toInt()

    view.addView(popupView)
    popupView.addView(titleLabel)

    titleLabel.layoutParams = ConstraintLayout.LayoutParams(
      ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
      ConstraintLayout.LayoutParams.WRAP_CONTENT)
    titleLabel.text = message


    popupView.layoutParams = ConstraintLayout.LayoutParams(
      ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
      ConstraintLayout.LayoutParams.WRAP_CONTENT)

    val popupConstraintSet = ConstraintSet()

    popupConstraintSet.connect(popupView.id, START, view.id, START, margin)
    popupConstraintSet.connect(popupView.id, END, view.id, END, margin)
    popupConstraintSet.centerHorizontally(popupView.id, view.id)
    popupConstraintSet.centerVertically(popupView.id, view.id)

    view.setConstraintSet(popupConstraintSet)
    setContentView(view)
  }
}

【问题讨论】:

  • 你是不是缺少视图的 TOP 和 BOTTOM 约束?
  • 也许,虽然我已经向 popupView 添加了一个约束集,它连接了 titleLabel 和 popupView 顶部、底部、开始、结束,但它也没有呈现。不知道还能尝试什么。

标签: android kotlin android-constraintlayout


【解决方案1】:

您可以通过在连接函数中切换 view#id 的顺序来解决此问题

popupConstraintSet.connect(view.id, START, popupView.id, START, margin)
popupConstraintSet.connect(view.id, END, popupView.id, END, margin)
popupConstraintSet.centerHorizontally(view.id, popupView.id)
popupConstraintSet.centerVertically(view.id, popupView.id)

或将 ConstraintSet 设置为 popUpView。该字段已经具有正确的名称^^

popUpView.setConstraintSet(popupConstraintSet)

【讨论】:

    【解决方案2】:

    这是我最终做的:

    • 移除 popupView.layoutParams;高度的 WRAP_CONTENT 似乎被忽略了...
    • 将带有 WRAP_CONTENT 的约束高度添加到约束集

    onCreate 现在是这样的:

      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        view.id = 1
        popupView.id = 2
        titleLabel.id = 5
    
        popupView.addView(titleLabel)
        view.addView(popupView)
    
        titleLabel.layoutParams = ConstraintLayout.LayoutParams(
          ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
          ConstraintLayout.LayoutParams.WRAP_CONTENT)
        titleLabel.text = message
    
    
        var margin = 2 * Constants.SpacingStandard.toInt()
        val popupConstraintSet = ConstraintSet()
    
        popupConstraintSet.connect(popupView.id, START, view.id, START, margin)
        popupConstraintSet.connect(popupView.id, END, view.id, END, margin)
        popupConstraintSet.constrainHeight(popupView.id, ConstraintSet.WRAP_CONTENT)
        popupConstraintSet.centerHorizontally(popupView.id, view.id)
        popupConstraintSet.centerVertically(popupView.id, view.id)
    
        view.setConstraintSet(popupConstraintSet)
    
        setContentView(view)
      }
    }
    

    【讨论】: