RecyclerView + GridLayoutManager: Resizing items to fit the screen and preserve ratio
Asked Answered
S

1

7

I'm trying to use RecyclerView and GridLayoutManager to display a list of items.

Here are the criteria which I want to satisfy:

  • Each row has a number of items specified by spanCount
  • Each item takes up an equal portion of the screen and together they fill up the whole screen.
  • An item height is determined by its width and a specified ratio.

I found that if I set android:layout_width="match_parent" on the item view, then the item width will be set by dividing RecyclerView's width by spanCount.

The problem is that I don't know to make item height proportional to its width as determined by the layout manager.

My only solution is to forego layout manager for measurements, and to explicitly set item dimensions in onBindViewHolder:

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_layout, parent, false);

    ViewGroup.LayoutParams p = v.getLayoutParams();

    p.width = parent.getWidth() / mLayoutManager.getSpanCount();
    p.height = p.width * 3/2;

    v.setLayoutParams(p);

    return new MyViewHolder(v);
}

I will appreciate any pointers which will help me improve my solution.

Sheikh answered 22/2, 2018 at 8:53 Comment(0)
P
16

How about using a ConstraintLayout in your item_layout xml. Constraint layout lets you set the height as a ratio of the width.

For example:

    <android.support.constraint.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">

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintDimensionRatio="3:2"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    </android.support.constraint.ConstraintLayout>

So when you use app:layout_constraintDimensionRatio="3:2" You are setting a ratio of 3 width for 2 height.

This should work regardless of span count

Petigny answered 22/2, 2018 at 9:4 Comment(3)
Okay, for example I developing app for Android TV and in my variant app:layout_constraintDimensionRatio is 16:9. But what will be when TV has 16:10 or 4:3?Drew
This is something that actually helped in my case after trying everything else.Bailment
i also made a similar proposal here: https://mcmap.net/q/1477281/-gridlayoutmanager-spacing-is-not-consistentGerbil

© 2022 - 2024 — McMap. All rights reserved.