Is there any way of using ConstraintLayout's Flow helper widget programmatically?

6.2k Views Asked by At

I want to use ConstraintLayout's Flow widget but when I search I can't find any example about using Flow widget programmatically.

How can I set constraint_referenced_ids programmatically?

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.helper.widget.Flow
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="text1,text2"
        app:flow_horizontalBias="0"
        app:flow_horizontalGap="10dp"
        app:flow_horizontalStyle="packed"
        app:flow_verticalBias="0"
        app:flow_wrapMode="chain"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
2

There are 2 best solutions below

1
user2424380 On

This works for me:

My custom PerkFlow class:

class PerkFlow(context: Context, attrs: AttributeSet?) : Flow(context, attrs) {

fun setup(
    parentView: ViewGroup,
    perks: List<String>
) {
    val referencedIds = IntArray(perks.size)
    for (i in perks.indices) {
        val textView = createTextView(context)
        textView.text = perks[i]
        textView.id = View.generateViewId()

        parentView.addView(textView)
        referencedIds[i] = textView.id
    }
    this.referencedIds = referencedIds
}

private fun createTextView(context: Context): TextView {
    val textView = TextView(context)
    textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12F)
    textView.setTextColor(context.resources.getColor(R.color.gmm_white))
    return textView
}
}

my xml:

  <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

..... (a lot of other code)

  <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/vendor_details_perks_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/vendor_details_favourite">

            <com.perkapp.mobile.views.PerkFlow
                android:id="@+id/vendor_details_perks"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                app:flow_horizontalBias="0"
                app:flow_horizontalGap="5dp"
                app:flow_horizontalStyle="packed"
                app:flow_verticalBias="0"
                app:flow_verticalGap="2dp"
                app:flow_wrapMode="chain"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>

 ..... (a lot of other code)

 </androidx.constraintlayout.widget.ConstraintLayout>

The setup of the PerkFlow in Fragment:

  binding.vendorDetailsPerks.setup(
            binding.vendorDetailsPerksContainer,
            listOf("apple, banana, blackberries, blueberries, cherries, grapes, lemon, orange, peaches, pear, pineapple, plums, raspberries, strawberries, watermelon ")
        )

Hope this helps!

And one more thing: if you call this again (in RecyclerView item, or new data arrives), don't forget to clear the parent view or the elements will be duplicated. I can send that code too if needed.

1
Adil Hussain On

Option 1

You can update a Flow layout's reference IDs at runtime by means of the Flow.setReferenceIds(ids:) method.

Note that the Flow.setReferenceIds(ids:) method (in its current form) does not request a layout so you may need to call Flow.requestLayout() as well as Flow.setReferenceIds(ids:).

Option 2

You can add and remove Views to/from a Flow layout by means of the Flow.addView(view:) and Flow.removeView(view:) methods.

Option 3

If you know all of the Views that you want to place inside of your Flow layout ahead of time and you just want to toggle which ones are hidden and displayed on demand, then you're best adding all of the Views to your Flow layout ahead of time and just toggling the visibility of the Views between GONE and VISIBLE as needed.