0

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Sunny
  • 7,444
  • 22
  • 63
  • 104
  • The "50" in your ConstraintSet connect code is `50px` while you XML has `50dp` which will more than likely be larger than the `50px`. Convert the `50dp` to pixels in your code and try it. – Cheticamp Feb 16 '20 at 19:53
  • still doesn't work. Even it were 50px only, the other image would show a little bit. but only one image shows – Sunny Feb 16 '20 at 22:40
  • OK. Still needs to be changed. I'll take another look. – Cheticamp Feb 16 '20 at 22:44

1 Answers1

1

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:

  • Create a view (make sure to generate an id)
  • Add view to layout (with appropriate layout params)
  • Repeat above for each view
  • Clone the constraint set from the layout
  • Make all the connections for the new views in the constraint set
  • Apply the constraint set to the layout.

Make this change and you will be one step closer.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131