Search code examples
androidandroid-layoutandroid-constraintlayout

Evenly spread views inside a cardview Horizontaly


I need help, I have ConstraintLayout and a few child views, I also have a card view which is a child view of the ConstraintLayout, I need to spread it evenly 3 views on the card view using only one ConstraintLayout to keep the flat hierarchy

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/black"
    android:padding="@dimen/padding_normal">

    <com.google.android.material.imageview.ShapeableImageView
        android:id="@+id/profile_image"
        android:layout_width="84dp"
        android:layout_height="84dp"
        android:backgroundTint="@color/black"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_person" />

    <TextView
        android:id="@+id/full_name"
        style="@style/Material.Headline6.Light"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/none"
        app:layout_constraintStart_toEndOf="@id/profile_image"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="Roger Mphile Nkosi" />

    <TextView
        android:id="@+id/job_title"
        style="@style/Material.Subtitle1.Light"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/none"
        app:layout_constraintStart_toEndOf="@id/profile_image"
        app:layout_constraintTop_toBottomOf="@id/full_name"
        tools:text="Android Developer" />
    
    <androidx.cardview.widget.CardView
        app:layout_constraintTop_toBottomOf="@id/job_title"
        app:layout_constraintStart_toEndOf="@id/profile_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >


    <TextView
        android:id="@+id/years_title"
        style="@style/Material.Caption.Light"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toStartOf="@+id/coffees_title"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toEndOf="@+id/profile_image"
        app:layout_constraintTop_toBottomOf="@id/job_title"
        tools:text="Years" />

    <TextView
        android:id="@+id/coffees_title"
        style="@style/Material.Caption.Light"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toStartOf="@+id/bugs_title"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toEndOf="@+id/years_title"
        app:layout_constraintTop_toBottomOf="@id/job_title"
        app:layout_constraintVertical_chainStyle="packed"
        tools:text="Coffees" />

    <TextView
        android:id="@+id/bugs_title"
        style="@style/Material.Caption.Light"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/coffees_title"
        app:layout_constraintTop_toBottomOf="@id/job_title"
        tools:text="Bugs" />
    
    </androidx.cardview.widget.CardView>
    
</androidx.constraintlayout.widget.ConstraintLayout>

I have tried chain styles but no winning. Is it possible to achieve what I want to achieve using only one ConstraintLayout?


Solution

  • The main problem here is with your xml structure of the 3 views which are direct children of the CardView instead of a ConstraintLayout so any constraints attributes you apply there cannot work because the direct parent is the CardView.

    Therefore your structure should look like this:

    <androidx.cardview.widget.CardView>
        <androidx.constraintlayout.widget.ConstraintLayout>
            <TextView android:id="@+id/years_title"/>
            <TextView android:id="@+id/coffees_title" />
            <TextView android:id="@+id/bugs_title"/>
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.cardview.widget.CardView>
    

    Now to evenly spread the above 3 views in the ConstraintLayout horizontally you have to apply for each TextView the attribute app:layout_constraintHorizontal_weight="1", the android:layout_width="0dp" and link every TextView child with its neighbours eg. for the second TextView will be: app:layout_constraintStart_toEndOf="@+id/years_title" , app:layout_constraintEnd_toStartOf="@+id/bugs_title".

    So your new structure of the CardView should look like the below:

    <androidx.cardview.widget.CardView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/job_title"
        app:layout_constraintStart_toEndOf="@id/profile_image"
        app:layout_constraintEnd_toEndOf="parent">
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white">
    
            <TextView
                android:id="@+id/years_title"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:background="@android:color/holo_blue_dark"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/coffees_title"
                app:layout_constraintHorizontal_weight="1"
                tools:text="Years" />
    
            <TextView
                android:id="@+id/coffees_title"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:background="@android:color/holo_orange_dark"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toEndOf="@+id/years_title"
                app:layout_constraintEnd_toStartOf="@+id/bugs_title"
                app:layout_constraintHorizontal_weight="1"
                tools:text="Coffees" />
    
            <TextView
                android:id="@+id/bugs_title"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:background="@android:color/holo_green_dark"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toEndOf="@+id/coffees_title"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_weight="1"
                tools:text="Bugs" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </androidx.cardview.widget.CardView>
    

    Result:

    result1_image

    Or in case you want the CardView to wrap to its content it should look like this:

    <androidx.cardview.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/job_title"
        app:layout_constraintStart_toEndOf="@id/profile_image">
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    
            <TextView
                android:id="@+id/years_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:background="@android:color/holo_blue_dark"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/coffees_title"
                app:layout_constraintHorizontal_weight="1"
                tools:text="Years" />
    
            <TextView
                android:id="@+id/coffees_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:background="@android:color/holo_orange_dark"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toEndOf="@+id/years_title"
                app:layout_constraintEnd_toStartOf="@+id/bugs_title"
                app:layout_constraintHorizontal_weight="1"
                tools:text="Coffees" />
    
            <TextView
                android:id="@+id/bugs_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:background="@android:color/holo_green_dark"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toEndOf="@+id/coffees_title"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_weight="1"
                tools:text="Bugs" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </androidx.cardview.widget.CardView>
    

    Result:

    reasult2_image