I have the following xml:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/image1"
layout="@layout/layout_circular_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"
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>
Now, these are 3 image layouts which are being used within the constraint layout. But I would like to do this dynamically since the number of image views can change. So I created the following class:
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()
}
}
When childImages
list is set, only one image is displayed within the layout when I do it programatically. But it works perfectly when I hardcode it via the XML shown above.
Could someone please help me understand what is wrong with the code above?
You are trying to connect views in the layout before they are added. The general sequence to add and connect views to a ConstraintLayout is:
Make this change and you will be one step closer.