Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 911
mpontus Avatar asked Feb 22 '18 08:02

mpontus


1 Answers

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

like image 64
Eoin Avatar answered Nov 14 '22 09:11

Eoin