Android:无法在约束布局中以编程方式正确添加约束集

Posted

技术标签:

【中文标题】Android:无法在约束布局中以编程方式正确添加约束集【英文标题】:Android: Unable to add Constraint Set correctly programmatically in Constraint Layout 【发布时间】:2020-05-31 07:34:20 【问题描述】:

我有以下 xml:

<androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/layout"
            android:layout_
            android:layout_>

                <include
                    android:id="@+id/image1"
                    layout="@layout/layout_circular_image"
                    android:layout_
                    android:layout_
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintHorizontal_bias="0"
                    app:layout_constraintVertical_bias="0"/>

                <include
                    android:id="@+id/image2"
                    layout="@layout/layout_circular_image"
                    android:layout_marginStart="50dp"
                    android:layout_
                    android:layout_
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="@+id/image1"
                    app:layout_constraintEnd_toEndOf="@+id/image1"
                    app:layout_constraintHorizontal_bias="0"
                    app:layout_constraintVertical_bias="0"/>

                <include
                    android:id="@+id/image3"
                    layout="@layout/layout_circular_image"
                    android:layout_marginStart="50dp"
                    android:layout_
                    android:layout_
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="@+id/image2"
                    app:layout_constraintEnd_toEndOf="@+id/image2"
                    app:layout_constraintHorizontal_bias="0"
                    app:layout_constraintVertical_bias="0"/>

        </androidx.constraintlayout.widget.ConstraintLayout>

现在,这些是在约束布局中使用的 3 个图像布局。但我想动态地这样做,因为图像视图的数量可以改变。 所以我创建了以下类:

class MultipleCircularImagesLayout : ConstraintLayout 

lateinit var binding: LayoutMultipleCircularImagesBinding

constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) 
    init(context)


constructor(context: Context) : super(context) 
    init(context)


constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) 
    init(context)


private fun init(context: Context) 
    binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.layout_multiple_circular_images, this, true)


var childImages: List<String> = emptyList()
set(value) 
    field = value

    var previousCircularImageLayout: CircularImageLayout? = null

    for(url in value) 

        val circularImageLayout = CircularImageLayout(context)
        circularImageLayout.id = View.generateViewId()

        val params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)


        val constraintSet = ConstraintSet()
        constraintSet.clone(binding.layout)

        constraintSet.connect(circularImageLayout.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
        constraintSet.connect(circularImageLayout.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)

        if (previousCircularImageLayout != null) 
            constraintSet.connect(circularImageLayout.id, ConstraintSet.START, previousCircularImageLayout.id, ConstraintSet.START, 50)
            constraintSet.connect(circularImageLayout.id, ConstraintSet.END, previousCircularImageLayout.id, ConstraintSet.END)
         else 
            constraintSet.connect(circularImageLayout.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START)
            constraintSet.connect(circularImageLayout.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
            constraintSet.setHorizontalBias(circularImageLayout.id, 0f)
        
        circularImageLayout.layoutParams = params
        constraintSet.applyTo(this)

        binding.layout.addView(circularImageLayout)
        ImageUtils.loadImage(url, circularImageLayout.binding.image)
        previousCircularImageLayout = circularImageLayout
    

    invalidate()


当设置childImages 列表时,当我以编程方式执行时,布局中只显示一个图像。但是当我通过上面显示的 XML 对其进行硬编码时,它可以完美运行。

有人可以帮我理解上面的代码有什么问题吗?

【问题讨论】:

ConstraintSet 连接代码中的“50”是 50px,而 XML 中的 50dp 很可能比 50px 大。将50dp 转换为代码中的像素并尝试一下。 还是不行。即使它只有 50px,其他图像也会显示一点。但只有一张图片显示 好的。还是需要改的。我再看看。 【参考方案1】:

您正在尝试在添加视图之前连接布局中的视图。将视图添加和连接到 ConstraintLayout 的一般顺序是:

创建视图(确保生成 id) 向布局添加视图(使用适当的布局参数) 对每个视图重复上述操作 从布局中克隆约束集 为约束集中的新视图建立所有连接 将约束集应用到布局。

进行此更改,您将更近一步。

【讨论】:

以上是关于Android:无法在约束布局中以编程方式正确添加约束集的主要内容,如果未能解决你的问题,请参考以下文章

有啥方法可以在 Swift 中以编程方式获取所有应用的自动布局约束

如何在 ios 中以编程方式添加约束

以编程方式设置的 Android 约束布局不正确

如何在 ios swift 中以编程方式创建自动布局等宽约束?

如何在ios swift中以编程方式创建自动布局等宽度约束?

在 iOS 8 中以编程方式将视图中的按钮居中使用约束