androidandroid-layoutandroid-layout-weight

Android Layout : LinearLayout equal size circles


I am trying to create the layout as seen below.

enter image description here

So far I have the following, however I'm afraid that, based on the screen resolution, the circles could become skewed since I'm hardcoding the height on the main container.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="85dp"
    android:baselineAligned="false"
    android:padding="10dp"
    android:weightSum="5">

    <RelativeLayout
        android:id="@+id/layoutAvatarItem1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="5dp"
        android:layout_weight="1"
        android:background="@drawable/circle_drawable_color_1">

        <CircleImageView
            android:id="@+id/imgAvatarItem1"
            android:layout_width="80dp"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:contentDescription="@string/general_content_desc"
            app:civ_border_color="@color/AppRed"
            app:civ_border_width="2dp" />

        <com.wang.avi.AVLoadingIndicatorView
            android:id="@+id/imgAvatarLoader1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:visibility="gone"
            app:indicatorColor="@color/White"
            app:indicatorName="BallPulseIndicator" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/layoutAvatarItem2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginStart="5dp"
        android:layout_marginEnd="5dp"
        android:layout_weight="1"
        android:background="@drawable/circle_drawable_color_1">

        <CircleImageView
            android:id="@+id/imgAvatarItem2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:contentDescription="@string/general_content_desc"
            app:civ_border_color="@color/AppRed"
            app:civ_border_width="2dp" />

        <com.wang.avi.AVLoadingIndicatorView
            android:id="@+id/imgAvatarLoader2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:visibility="gone"
            app:indicatorColor="@color/White"
            app:indicatorName="BallPulseIndicator" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/layoutAvatarItem3"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginStart="5dp"
        android:layout_marginEnd="5dp"
        android:layout_weight="1"
        android:background="@drawable/circle_drawable_color_1">

        <CircleImageView
            android:id="@+id/imgAvatarItem3"
            android:layout_width="80dp"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:contentDescription="@string/general_content_desc"
            app:civ_border_color="@color/AppRed"
            app:civ_border_width="2dp" />

        <com.wang.avi.AVLoadingIndicatorView
            android:id="@+id/imgAvatarLoader3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:visibility="gone"
            app:indicatorColor="@color/White"
            app:indicatorName="BallPulseIndicator" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/layoutAvatarItem4"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginStart="5dp"
        android:layout_marginEnd="5dp"
        android:layout_weight="1"
        android:background="@drawable/circle_drawable_color_1">

        <CircleImageView
            android:id="@+id/imgAvatarItem4"
            android:layout_width="80dp"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:contentDescription="@string/general_content_desc"
            app:civ_border_color="@color/AppRed"
            app:civ_border_width="2dp" />

        <com.wang.avi.AVLoadingIndicatorView
            android:id="@+id/imgAvatarLoader4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:visibility="gone"
            app:indicatorColor="@color/White"
            app:indicatorName="BallPulseIndicator" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/layoutAvatarItem5"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginStart="5dp"
        android:layout_weight="1"
        android:background="@drawable/circle_drawable_color_1">

        <CircleImageView
            android:id="@+id/imgAvatarItem5"
            android:layout_width="80dp"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:contentDescription="@string/general_content_desc"
            app:civ_border_color="@color/AppRed"
            app:civ_border_width="2dp" />

        <com.wang.avi.AVLoadingIndicatorView
            android:id="@+id/imgAvatarLoader5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:visibility="gone"
            app:indicatorColor="@color/White"
            app:indicatorName="BallPulseIndicator" />

    </RelativeLayout>

</LinearLayout>

Circle_drawable_color_1 XML

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/BackgroundColor1" />
    <stroke
        android:width="1dp"
        android:color="@color/AppRed"/>
</shape>

How can I create the layout above as a LinearLayout, horizontal orientation with 5 of my Relative layouts within it so that as the screen size grows/shrinks, the circles will also grow/shrink?

Thank you!


Solution

  • To achieve responsive UI, first you need to get rid of hard coded values

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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" <!-- make it wrap so it can grow -->
        android:baselineAligned="false"
        android:padding="10dp"
        android:weightSum="5">
    
        <RelativeLayout
            android:id="@+id/layoutAvatarItem1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="5dp"
            android:layout_weight="1"
            android:background="@drawable/circle_drawable_color_1">
    
            <CircleImageView
                android:id="@+id/imgAvatarItem1"
                android:layout_width="match_parent" 
               <!-- make it match, so it stretches to fit -->
                android:layout_height="match_parent"
                android:layout_alignParentStart="true"
                android:layout_centerVertical="true"
                android:contentDescription="@string/general_content_desc"
                app:civ_border_color="@color/AppRed"
                app:civ_border_width="2dp" />
    
            <com.wang.avi.AVLoadingIndicatorView
                android:id="@+id/imgAvatarLoader1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_marginStart="20dp"
                android:layout_marginEnd="20dp"
                android:visibility="gone"
                app:indicatorColor="@color/White"
                app:indicatorName="BallPulseIndicator" />
    
        </RelativeLayout>
        <!-- repeat for other four circles -->
    </LinearLayout>
    

    Now LinearLayout will fit in width and divide the items equally based on available screen width, so width of your circles are calculated based on screen size, now all you need to do is to match the height of the circle to it's width in Java/kotlin

    layoutAvatarItem1.post { 
        layoutAvatarItem1.layoutParams = (layoutAvatarItem1.layoutParams as LinearLayout.LayoutParams).apply { 
            height = width
        }
    }
    

    You can do same for all the other circles