【问题标题】:I am not able to give programatically constraint correctly我无法正确地以编程方式给出约束
【发布时间】:2022-11-16 02:29:33
【问题描述】:

我有两个按钮验证和通知,如下图所示的 XML 格式。

我想以编程方式在通知按钮下方显示验证按钮。如下图所示

我已经实现了下面提到的 kotlin 代码和代码剪裁:


fun changeConstraint() {
    val valetBtnParent = binding.root.findViewById<ConstraintLayout>(R.id.childLayout)
    ConstraintSet().apply {
        val layoutParams = ConstraintLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
        clone(valetBtnParent)
        clear(R.id.button_validate, ConstraintSet.END)
        clear(R.id.button_validate, ConstraintSet.BOTTOM)
        clear(R.id.button_validate, ConstraintSet.START)
        connect(R.id.button_validate, ConstraintSet.BOTTOM, R.id.detail_cardview, ConstraintSet.TOP, ZERO)
        connect(R.id.button_validate, ConstraintSet.END, R.id.detail_cardview, ConstraintSet.END, ZERO)
        connect(R.id.button_validate, ConstraintSet.START, R.id.button_notify, ConstraintSet.BOTTOM, TWO_HUNDRED)
        applyTo(childLayout)
    }
}

请帮我!!!!

【问题讨论】:

  • 如果可以,请发布 XML。 childLayout 定义为什么?您定义但似乎没有使用layoutParams。您正在克隆valetBtnParent,但将约束集应用于childLayout。你确定这是你想做的吗?

标签: android kotlin android-constraintlayout


【解决方案1】:

您错过的一件非常重要的事情是您的 XML 布局,这在帮助 ContraintLayout 动画时非常重要,因为它告诉我们现有的约束是什么,但让我们只处理提供的代码:

这似乎是预期的结果:

要实现它:您必须清除button_validateStart(以及Bottom,如果正在使用)的TopBottomEnd约束。

为此,您可以将代码更改为:

fun changeConstraint() {
    ConstraintSet().apply {
        clone(binding.childLayout)
        clear(binding.buttonValidate.id, ConstraintSet.TOP)
        clear(binding.buttonValidate.id, ConstraintSet.BOTTOM)
        clear(binding.buttonValidate.id, ConstraintSet.END)
        clear(binding.buttonNotify.id, ConstraintSet.START)
        connect(binding.buttonValidate.id, ConstraintSet.BOTTOM, binding.detailCardview.id, ConstraintSet.TOP)
        connect(binding.buttonValidate.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
        connect(binding.buttonValidate.id, ConstraintSet.TOP, binding.buttonNotify.id, ConstraintSet.BOTTOM, TWO_HUNDRED)
        connect(binding.buttonNotify.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START)
        applyTo(binding.childLayout)
    }
}

假设 detail_cardview 在这些按钮下方,上面的代码应该可以正常工作。

要在更改约束时添加动画,请将这些行粘贴到包含 applyTo() 的最后一行上方:

val transition: Transition = ChangeBounds()
transition.interpolator = AccelerateInterpolator(1.0f)
transition.duration = 400
TransitionManager.beginDelayedTransition(binding.childLayout, transition)

如果需要添加动画侦听器,您可以查看我对ConstraintSet animation here 的其他回答。

因为您已经在使用视图绑定,所以没有使用静态 ID 的逻辑,我也将它们更改为绑定 ID。这应该可以工作,即使您的代码不完整。请告诉我是否有遗漏。

此外,为了实现 GIF 中所见的输出,我用于 GIF 的代码如下:

<!-- begin snippet: js hide: true -->
//To change the constraints to the new position
private fun changeConstraint() {
    ConstraintSet().apply {
        clone(binding.childLayout)
        clear(binding.buttonValidate.id, ConstraintSet.END)
        clear(binding.buttonNotify.id, ConstraintSet.START)
        clear(binding.buttonValidate.id, ConstraintSet.TOP)
        clear(binding.buttonValidate.id, ConstraintSet.BOTTOM)
        connect(
            binding.buttonValidate.id,
            ConstraintSet.END,
            ConstraintSet.PARENT_ID,
            ConstraintSet.END
        )
        connect(
            binding.buttonValidate.id,
            ConstraintSet.TOP,
            binding.buttonNotify.id,
            ConstraintSet.BOTTOM
        )
        connect(
            binding.buttonNotify.id,
            ConstraintSet.START,
            ConstraintSet.PARENT_ID,
            ConstraintSet.START
        )
        val transition: Transition = ChangeBounds()
        transition.interpolator = AccelerateInterpolator(1.0f)
        transition.duration = 400
        TransitionManager.beginDelayedTransition(binding.childLayout, transition)
        applyTo(binding.childLayout)
        isChanged = true
    }
}

//To change the constraints back to the original position
private fun changeConstraintBack() {
    ConstraintSet().apply {
        clone(binding.childLayout)
        clear(binding.buttonValidate.id, ConstraintSet.END)
        clear(binding.buttonNotify.id, ConstraintSet.START)
        clear(binding.buttonValidate.id, ConstraintSet.TOP)
        connect(
            binding.buttonValidate.id,
            ConstraintSet.END,
            binding.buttonNotify.id,
            ConstraintSet.START,
            5
        )
        connect(
            binding.buttonValidate.id,
            ConstraintSet.TOP,
            ConstraintSet.PARENT_ID,
            ConstraintSet.TOP
        )
        connect(
            binding.buttonValidate.id,
            ConstraintSet.BOTTOM,
            ConstraintSet.PARENT_ID,
            ConstraintSet.BOTTOM
        )
        connect(
            binding.buttonNotify.id,
            ConstraintSet.START,
            binding.buttonValidate.id,
            ConstraintSet.END
        )
        val transition: Transition = ChangeBounds()
        transition.interpolator = AccelerateInterpolator(1.0f)
        transition.duration = 400
        TransitionManager.beginDelayedTransition(binding.childLayout, transition)
        applyTo(binding.childLayout)
        isChanged = false
    }
}

【讨论】:

    【解决方案2】:

    在我看来,最简单的方法是将它们插入线性布局并将方向从水平更改为垂直。

    【讨论】:

      猜你喜欢
      • 2020-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 2018-11-25
      相关资源
      最近更新 更多