Search code examples
androidandroid-layoutlistview

How can I use layout_weight in RecyclerView or ListView item view to have items of equal height fill up the available space on screen?


I currently have a need to use a RecyclerView (or ListView) but the number of items is fixed at 4. I want those 4 items to equally use the available space on the screen. The RecyclerView is the only view on the screen except for the app bar. I.e. RecyclerView has layout_height set to match_parent. I chose the RecyclerView because the items have different layouts depending on model state.

I haven't looked it up yet, but I'm sure I can set the height programmatically in Java code for each item. But that seems inelegant if I can specify it in the XML. Similar questions to my right, as I write this, answer that question.

I've tried the following in the item_layout.xml file, the way layout_weight is used in other scenarios:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_weight="1"
    android:layout_height="0dp">...</LinearLayout>

But then nothing shows on screen.

What I'd like to know is, can I do this in the layout XML with layout_weight, or something else? If so, how?


Solution

  • As the API reference says, layout_weight is an attribute of LinearLayout, so it cannot be used with other ViewGroups like, for instance, RecyclerView and ListView. Instead, you have to set the item's height programmatically.

    Since you seem worried about your code's cleanliness, I think this is a rather elegant solution in case you use a RecyclerView:

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater
                .from(parent.getContext())
                .inflate(R.layout.item_list, null);
    
        int height = parent.getMeasuredHeight() / 4;
        int width = parent.getMeasuredWidth();
    
        view.setLayoutParams(new RecyclerView.LayoutParams(width, height));
    
        return new ViewHolder(view);
    }