Android GridLayoutManager Example

By Arvind Rai, July 18, 2023
On this page we will learn to use RecyclerView GridLayoutManager in our Android application.
1. The GridLayoutManager lays out items in a grid. This is the implementation of RecyclerView.LayoutManager class. The RecyclerView is used to display large set of data efficiently.
2. The items in our RecyclerView are arranged by RecyclerView.LayoutManager class. The RecyclerView API provides three layout managers.
a. LinearLayoutManager : Arranges the items in a one-dimensional list.
b. GridLayoutManager : Arranges the items in a two-dimensional grid.
c. StaggeredGridLayoutManager : Arranges the items in staggered grid formation.

3. The items arranged by GridLayoutManager occupies 1 span in a grid by default. We can change it by providing a custom SpanSizeLookup instance via setSpanSizeLookup() method.

On this page we will discuss GridLayoutManager to lay out items in a grid. Find the print screen of our demo application output.
Android GridLayoutManager Example

GridLayoutManager

1. The GridLayoutManager is the implementation of RecyclerView.LayoutManager. The GridLayoutManager lays out items in a grid.
2. The RecyclerView.LayoutManager performs measuring and positioning item views within a RecyclerView. It also decides when to recycle item views that are no longer visible to the user.
3. The GridLayoutManager arranges the items in two-dimensional grid. We can arrange grid either vertically or horizontally.
4. If grid is arranged vertically, all the elements in each row have equal height and width. But in different rows, height may vary.
5. If grid is arranged horizontally, all the elements in each column have equal height and width. But in different columns, width may vary.
6. Find the constructors of GridLayoutManager class.
GridLayoutManager(Context context, int spanCount)

GridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) 
7. Find some methods of GridLayoutManager class.
int computeHorizontalScrollOffset(RecyclerView.State state)

RecyclerView.LayoutParams generateLayoutParams(Context c, AttributeSet attrs)

int getColumnCountForAccessibility(RecyclerView.Recycler recycler, RecyclerView.State state)

int getRowCountForAccessibility(RecyclerView.Recycler recycler, RecyclerView.State state)

int getSpanCount()

GridLayoutManager.SpanSizeLookup getSpanSizeLookup()

void setSpanSizeLookup(GridLayoutManager.SpanSizeLookup spanSizeLookup) 

Creating GridLayoutManager

In our demo application, we are using GridLayoutManager to create a grid with 2 column.
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2); 
Set layout manager to RecyclerView.
RecyclerView recyclerView = findViewById(R.id.communication);
recyclerView.setLayoutManager(gridLayoutManager); 

setSpanSizeLookup()

The setSpanSizeLookup is a method of GridLayoutManager and is used to change number of span occupied by an item. By default, each item occupies 1 span. We can set custom SpanSizeLookup via setSpanSizeLookup method. Find its method declaration from Android doc.
void setSpanSizeLookup(GridLayoutManager.SpanSizeLookup spanSizeLookup) 
We are creating a custom SpanSizeLookup that will provide 1 span for all the items of list. If the size of list is odd, the last item will occupy 2 span.
GridLayoutManager.SpanSizeLookup onSpanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        final int len = communications.size();
        return (len % 2 == 1 && len -1 == position)? 2 : 1;
    }
};
gridLayoutManager.setSpanSizeLookup(onSpanSizeLookup); 

Complete Example

res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/communication"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> 
res/layout/row_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="200dp"
    android:layout_gravity="center"
    android:layout_margin="7dp"
    app:cardCornerRadius="10dp"
    app:cardElevation="5dp"
    app:contentPadding="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/cmImageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/cmTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30sp" />
    </LinearLayout>
</androidx.cardview.widget.CardView> 
MyViewHolder.java
package com.cp.app;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;

public class MyViewHolder extends RecyclerView.ViewHolder  {
    TextView myTextView;
    ImageView myImageView;
    public MyViewHolder(View itemView) {
        super(itemView);
        myTextView = itemView.findViewById(R.id.cmTextView);
        myImageView = itemView.findViewById(R.id.cmImageView);
        itemView.setOnClickListener(view ->
                Snackbar.make(itemView.getRootView(), "Clicked on " + myTextView.getText(), Snackbar.LENGTH_LONG)
               .setAction("Action", null).show());
    }
} 
MyRecyclerViewAdapter.java
package com.cp.app;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyViewHolder> {

    private List<MyItem> myList;
    private LayoutInflater layoutInflater;
    public MyRecyclerViewAdapter(Context context, List<MyItem> data) {
        this.layoutInflater = LayoutInflater.from(context);
        this.myList = data;
    }
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = layoutInflater.inflate(R.layout.row_item, parent, false);
        return new MyViewHolder(view);
    }
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        MyItem item = myList.get(position);
        holder.myImageView.setImageResource(item.getImageId());
        holder.myTextView.setText(item.getName());
    }
    @Override
    public int getItemCount() {
        return myList.size();
    }
} 
MyItem.java
package com.cp.app;

public class MyItem {
    private String name;
    private int imageId;

    public MyItem(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }
    public String getName() {
        return name;
    }
    public int getImageId() {
        return imageId;
    }
} 
MainActivity.java
package com.cp.app;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    MyRecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List<MyItem> communications = new ArrayList<>();
        communications.add(new  MyItem("Call", R.drawable.ic_call));
        communications.add(new  MyItem("Chat", R.drawable.ic_chat));
        communications.add(new  MyItem("Comment", R.drawable.ic_comment));
        communications.add(new  MyItem("Duo", R.drawable.ic_duo));
        communications.add(new  MyItem("Email", R.drawable.ic_email));
        communications.add(new  MyItem("Notification", R.drawable.ic_notification));
        communications.add(new  MyItem("Voicemail", R.drawable.ic_voicemail));

        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
        // Using setSpanSizeLookup
        GridLayoutManager.SpanSizeLookup onSpanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                final int len = communications.size();
                return (len % 2 == 1 && len -1 == position)? 2 : 1;
            }
        };
        gridLayoutManager.setSpanSizeLookup(onSpanSizeLookup);

        RecyclerView recyclerView = findViewById(R.id.communication);
        recyclerView.setLayoutManager(gridLayoutManager);

        adapter = new MyRecyclerViewAdapter(this, communications);
        recyclerView.setAdapter(adapter);
    }
} 

Reference

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us