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.

mpontus
  • 2,143
  • 2
  • 19
  • 21

1 Answers1

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

Eoin
  • 4,050
  • 2
  • 33
  • 43
  • 1
    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? – kostyabakay Jan 04 '19 at 14:41
  • This is something that actually helped in my case after trying everything else. – VPZ Jul 20 '20 at 10:39
  • i also made a similar proposal here: https://stackoverflow.com/a/64619615/835883 – j2emanue Oct 31 '20 at 09:30