尝试以编程方式将视图添加到Kotlin中的ContraintLayout的奇怪行为

时间:2018-04-15 20:35:48

标签: android kotlin android-constraintlayout

我是从iOS开发者背景来到Android的,并且在以编程方式添加视图时让ConstraintLayout正常工作时遇到了一些困难。

我有一个非常简单的活动,包含一个ConstraintLayout和一个放在Android Studio设计窗口内的按钮。按下按钮时,我添加了一个textView和另一个按钮。我试图约束这些,使得它们与ConstraintLayout的顶部距离相同,并且textView的前沿被约束到ConstraintLayout的左侧,并且该按钮被约束到ConstraintLayout的右侧。

我的XML如下:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/parentViewConstraintLayout"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="@android:color/holo_orange_dark"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/addWidgetButton"
       style="@style/Widget.AppCompat.Button.Borderless"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:layout_centerHorizontal="true"
       android:layout_marginBottom="28dp"
       android:layout_marginEnd="8dp"
       android:layout_marginStart="8dp"
       android:fontFamily="@font/muli_bold"
       android:text="Add New Widget"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent" />

</android.support.constraint.ConstraintLayout>

有问题的Kotlin

addWidgetButton.setOnClickListener() {

    val textView = TextView(this)
    textView.setTextColor(Color.BLACK)
    textView.setTextSize(20f)
    textView.setText("Text message for testing")

    val newButton = Button(this)
    newButton.setText("Push me")

    parentViewConstraintLayout.addView(textView)
    parentViewConstraintLayout.addView(newButton)

    val constraintSet = ConstraintSet()
    constraintSet.clone(parentViewConstraintLayout)

    constraintSet.connect(textView.id, ConstraintSet.TOP, parentViewConstraintLayout.id, ConstraintSet.TOP, 10)
    constraintSet.connect(textView.id, ConstraintSet.START, parentViewConstraintLayout.id, ConstraintSet.START, 10)

    constraintSet.connect(newButton.id, ConstraintSet.END, parentViewConstraintLayout.id, ConstraintSet.END, 30)
    constraintSet.connect(newButton.id, ConstraintSet.TOP, parentViewConstraintLayout.id, ConstraintSet.TOP, 50)

    constraintSet.applyTo(parentViewConstraintLayout)
}

按下按钮时,我得到了以下行为,而不是预期的行为: enter image description here

如果我注释掉一些代码,以便我只添加一个视图(按钮或textView),它就能正常工作。他们之间有一些我不理解的奇怪的互动。

2 个答案:

答案 0 :(得分:3)

<div id="mainWrapper"> <div class="formWrap"> <form> <input placeholder="Enter Value" /> </form> </div> <div class="btnWrap"> <button>Submit</button> </div> </div>约束适用于资源ID。我看到您在哪里创建ConstraintLayoutTextView,但我看不到您为这些视图设置ID的位置。也许一些Kotlin魔术?

对于API 17+,您可以使用View.generateViewId()生成ID,并使用View.setId()进行设置。然后,您可以参考Button中的ID。现在他们都是View.NO_ID.

我还要补充一点,如果你想将父作为约束引用它是ConstraintSet.PARENT_ID

答案 1 :(得分:1)

  

我试图约束这些,使得它们与ConstraintLayout的顶部距离相同,并且textView的前沿被约束到ConstraintLayout的左侧,并且该按钮被约束到右侧ConstraintLayout。

好的,所以如果我没有弄错...你想要的是TextView和Button并排,对吗?

| [TextView] [Button]|

| [TextView][Button] |

| [TextView ][Button ]|

根据您的需要,约束必须不同。

另外,你说:

  

它们与ConstraintLayout顶部的距离相同

这意味着如果你一直按下按钮,它们将有效地位于前一个按钮之上,是这个意图吗?

或者你的意思是“我希望它们低于前一个,尊重”上边距“所以每个元素之间的垂直空间是相同的吗?”

在任何情况下,您应该(因为您正在使用CL 1.0.2)正确指定这些视图的所有属性。

考虑AutoLayout,除非View具有固有大小,否则您需要在算法确定视图必须去的位置之前固定开始/结束/顶部/底部。

无论如何回到你的样本......

我添加了

textView.id = View.generateViewId()

newButton.id = View.generateViewId()

并运行您的代码并且它可以正常工作......但每个新的“对”按钮/文本都会添加到顶部。

如果你需要|[Tv ][btn]|,你可以简单地添加这两个:

textView.layoutParams = Constraints.LayoutParams(ConstraintSet.MATCH_CONSTRAINT, ConstraintSet.WRAP_CONTENT)

constraintSet.connect(textView.id, ConstraintSet.END, newButton.id, ConstraintSet.START, 10)

应该给你那个。