androidandroid-recyclerviewgridlayoutmanager

Android, RecyclerView with GridLayoutManager and ImageView as cell content does not fit the vertical space


I'm trying to implement a simple grid of images.

Each image is the same size, the problem is that if I scale down the images (for example if I set a spanCount so that the gridlayout has to resize images to fit them) the "virtual-cell" that contains the image does not adapt to image size.

Here you can see the differences between spanCount=3 and spanCount=4.

enter image description hereenter image description here

If I use fitXY for the imageView this is the result, so the grid layout manager reduces the cell width but does not fit the cell height.

enter image description here

My grid layout xml:

       <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/grid"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
            app:spanCount="4"
            tools:itemCount="30"
            tools:listitem="@layout/image_item" />

And image_item.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView 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:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    tools:srcCompat="@tools:sample/avatars" />

My targets:

To be more clear, I need to remove the space marked red.

enter image description here


Solution

  • If I may try answering this, in your image_item.xml I would suggest you change the layout width to match_parent like this

    <?xml version="1.0" encoding="utf-8"?>
    <ImageView 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:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"
        tools:srcCompat="@tools:sample/avatars" />
    

    The logic behind this is since we already using GridLayout manager and our spanCount is 4, so the match_parent width will occupy all the space available to it, inside whatever spanCount is assigned.

    Secondly centerCrop would be better I feel. It can automatically adjust all your images without them looking stretched.

    EDIT: I feel you can get this done using the magic of ConstraintLayout, you will have to update your image_item.xml as follows

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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">
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            tools:srcCompat="@tools:sample/avatars"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    The logic here being the 0dp with GridLayout helps your image to occupy whatever width is available and dimensionRatio being one helps your width and height match equally.