androidandroid-recyclerviewandroid-constraintlayoutandroid-coordinatorlayout

Fluid height RecyclerView when full or empty


I have a dynamic recycler view. Which expands the height of its parent when full and looks really nice however when there are no entries added to it yet or there are few entries in it it just looks ugly.

However if I set the width to say 200dp than it looks a bit better.

    <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/shading"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="?android:attr/actionBarSize"
        android:background="@color/shading">

        <ImageView
            android:id="@+id/logo"
            android:layout_width="120dp"
            android:layout_height="60dp"
            android:src="@drawable/ic_logo"
            app:layout_constraintBottom_toTopOf="@+id/list_projects"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/list_projects"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_margin="20dp"
            android:background="@drawable/shape_list_item_projects"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/logo" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottomAppBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:backgroundTint="@color/white"
        app:fabCradleRoundedCornerRadius="25dp"
        app:fabCradleMargin="5dp"
        app:hideOnScroll="false"
        app:menu="@menu/menu_main_activity" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_outline_add_circle_outline_24"
        app:backgroundTint="@color/white"
        app:layout_anchor="@id/bottomAppBar"
        app:maxImageSize="40dp" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

The desired outcome is to have it wrap the content until it reaches the bounds of BottomAppBar.


Solution

  • You can do that by:

    1. Bias the RecyclerView to the top using ConstraintLayout vertical chain:

      app:layout_constraintVertical_bias="0"
      app:layout_constraintVertical_chainStyle="packed"
      

      This makes the RecyclerView directly under the top image, and pack both to the top of the layout.

    2. Force the RecyclerView default height dimension to wrap_content:

      app:layout_constraintHeight_default="wrap"
      

      This makes the RecyclerView to wrap its content when having 0 or few items until it reaches the bounds of BottomAppBar; then the RV will be strict to the constraint.

    3. Remove app:layout_constraintBottom_toTopOf="@+id/list_projects" from the top image to make the top image and RecyclerView aligned to the top (not centered vertically).