7

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>
Adil Hussain
  • 30,049
  • 21
  • 112
  • 147
hugerde
  • 919
  • 1
  • 12
  • 27

2 Answers2

5

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.

user2424380
  • 1,393
  • 3
  • 16
  • 29
  • Not sure how this works without setting any constraints on the added views. In a similar usage of mine all views will lay on top of each other. – Tyler Turnbull Aug 02 '22 at 12:20
2

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.

Adil Hussain
  • 30,049
  • 21
  • 112
  • 147