trethaller
trethaller

Reputation: 587

Making StaggeredGridLayout wrap content

I need to display a staggered grid within a linear layout.

enter image description here

For that I have used a StaggeredGridLayoutManager on a RecyclerView from android.support.v7.widget. The problem is that StaggeredGridLayoutManager doesn't support wrap_content.

There are other questions addressing the issue, but they are concerned with linear layouts, not staggered grids:

As far as I understand I could derive StaggeredGridLayoutManager and implement onMeasure. Is there a way do to that without recalculating the positions and sizes of the children myself? When looking at the StaggeredGridLayoutManager.java source, I can see that it uses ScrollbarHelper to approximate the size of the scrolling content. Is there a way to reuse that?

Upvotes: 3

Views: 1934

Answers (2)

Dpedrinha
Dpedrinha

Reputation: 4220

The problem is that when RecyclerView is drawn, it calculates all the remaining size to itself before drawing the next elements and don't recalculate after the other elements are drawn, leaving them outside the screen.

There is an easy fix for this problem: The trick is to draw all other elements first, and leave RecyclerView for last. Use a relative layout and put the RecyclerView last on the XML layout file. Since with relative layout you can put each element wherever you want independently of the order on the XML file, you will draw all elements before RecyclerView and this will make it calculate the accurate remaining space and wrap_content will work properly.

Example to add a paginagion bar below the RecyclerView:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity"
    >

    <LinearLayout
        android:id="@+id/pagination_btns"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true"> //HERE YOU ALIGN THIS ELEMENT TO THE BOTTOM OF THE PARENT
        <Button
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="@string/previous_btn_label"/>
        <Space
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="@string/next_btn_label"/>
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/items_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:layout_above="@id/pagination_btns"/> //HERE YOU ALIGN THE RECYCLERVIEW ABOVE THE PAGINATION BAR 


</RelativeLayout>

Upvotes: 2

trethaller
trethaller

Reputation: 587

I ended-up using a custom control for this, inspired by: https://github.com/expilu/AntipodalWall/blob/master/library/src/com/antipodalwall/AntipodalWallLayout.java

Upvotes: 1

Related Questions