androidxmlandroid-layoutandroid-constraintlayoutconstraintlayout-helper-widget-flow

Arranging ConstraintLayout Flow References From Bottom To Top And Right To Left


I need to fill ConstraintLayout Flow view from Bottom To Top And Right To Left. This is my code:

<androidx.constraintlayout.helper.widget.Flow
    android:id="@+id/flow"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    app:constraint_referenced_ids="tv1,tv2,tv3,tv4,tv5,tv6,tv7,tv8,tv9,tv10"
    app:flow_horizontalGap="8dp"
    app:flow_verticalGap="8dp"
    app:flow_verticalStyle="packed"
    app:flow_wrapMode="chain"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintHeight_percent=".5"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

And this is the result:

enter image description here

(In fact I'm going to set references dynamically due to the API response, so assume that the views are not in XML layout)

But I need the below one:

enter image description here

Any help is appreciated.


Solution

  • To arrange items from Bottom-to-Top and Right-to-Left you can use the FlexboxLayout Google Library. All you need is to use the below attributes in FlexboxLayout:

    1. app:flexDirection="column_reverse" This will draw each item from Bottom to Top.

    2. app:flexWrap="wrap_reverse" This will draw each item from Right to Left.

    3. app:justifyContent="flex_start" This will control the alignment of each item and we use flex_start to align it from bottom.

    Xml sample is like below:

    <?xml version="1.0" encoding="utf-8"?>
    <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <com.google.android.flexbox.FlexboxLayout
            android:id="@+id/flexLayout"
            android:layout_width="wrap_content"
            android:layout_height="300dp"
            app:flexDirection="column_reverse"
            app:flexWrap="wrap_reverse"
            app:justifyContent="flex_start"
            android:background="@android:color/white">
    
            <TextView
                android:id="@+id/tv1"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="1"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv2"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="2"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv3"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="3"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv4"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="4"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv5"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="5"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv6"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="6"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv7"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="7"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv8"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="8"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv9"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="9"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/tv10"
                android:layout_width="120dp"
                android:layout_height="65dp"
                android:background="@android:color/holo_orange_dark"
                android:gravity="center"
                android:layout_margin="5dp"
                android:text="10"
                android:textSize="18sp" />
    
        </com.google.android.flexbox.FlexboxLayout>
    
    </HorizontalScrollView>
    

    or Programmatically:

    val flexLayout: FlexboxLayout = findViewById<FlexboxLayout>(R.id.flexLayout)
    val itemWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120f, resources.displayMetrics).toInt()
    val itemHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65f, resources.displayMetrics).toInt()
    val itemMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5f, resources.displayMetrics).toInt()
    
    for (i in 0..9) {
        val tv = TextView(this)
        tv.text = (i + 1).toString()
        tv.setBackgroundColor(ContextCompat.getColor(this, android.R.color.holo_orange_dark))
        tv.gravity = Gravity.CENTER
        val params = FlexboxLayout.LayoutParams(itemWidth, itemHeight)
        params.setMargins(itemMargin, itemMargin, itemMargin, itemMargin)
        tv.layoutParams = params
        flexLayout.addView(tv)
    }
    

    Result:

    flexbox_layout