Android StaggeredGridLayoutManager Example Tutorial

Android StaggeredGridLayoutManager Example Tutorial

In this tutorial we are going to learn how to create a simple android application that demonstrate the use of android StaggeredGridLayoutManager.

According to Google android developers guide – A LayoutManager that lays out children in a staggered grid formation. It supports horizontal & vertical layout as well as an ability to layout children in reverse.

There are other different layout manger you can be used to layout your child views in a way that suits your application. You can use LinearLayoutManager or GridLayoutManager. For detailed android example tutorial on GridLayoutManager, I will suggest you read my post on Android GridLayoutManager with RecyclerView in Material Design.

We are not going to make use of Material Design in this android example tutorial but if you want to learn more about android Material Design and Navigation Drawer you should read my post on Android Navigation Drawer with Material Design.

Now lets briefly show case what we will like to achieve in this android tutorial. The screen shot below represent the user interface.

Android StaggeredGridLayoutManager Example Tutorial

If you are using a version of android Studio without support for updated version of appcompat V7 library, you should endeavor to add the compile dependency to your project build.gradle file.

We are also going to add two dependency libraries for Android RecyclerView and CardView. The updated build.gradle file will look as shown below.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile 'com.android.support:cardview-v7:21.0.+'
    compile 'com.android.support:recyclerview-v7:21.0.+'
}

Before we start, the first thing I will do is to list the environment and tools I used in this android tutorial but feel free to use whatever environment or tools you are familiar with.

Windows 7

Android Studio

Sony Xperia ZL

Min SDK 14

Target SDK 19

To create a new android application project, following the steps as stipulated below.

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidStaggeredGridLayoutManager

Package: com.inducesmile.androidstaggeredgridlayoutmanager

Keep other default selections.

Continue to click on next button until Finish button is active, then click on Finish Button

Once you are done with creating your project, make sure you change the package name if you did not use the same package.

First, we will copy all the images we will use for our application in the drawer folder. The image is provided in the download section or feel free to use your own images. I have added four images.

Open that main activity layout file (activity_main.xml) and copy and paste the following codes.

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical" />

</RelativeLayout>

We have added a RecyclerView in our main layout. We going to create a RecyclerView Adapter which we will use to bind our data source to RecyclerView component. Each item in the RecyclerView will represent an ImageView and a TextView.

The RecyclerView Adapter will extends RecyclerView.Adapter<SolventViewHolders> . The SolventViewHolder is a ViewHolder class that holds references to the View components of each item.

The RecyclerView Adapter must override two methods of its parent class – onCreateViewHolder(ViewGroup parent, int viewType)   and onBindViewHolder(SolventViewHolders holder, int position) 

Copy the code for the adapter as shown below.

package inducesmile.com.androidstaggeredgridlayoutmanager;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

public class SolventRecyclerViewAdapter  extends RecyclerView.Adapter<SolventViewHolders> {

    private List<ItemObjects> itemList;
    private Context context;

    public SolventRecyclerViewAdapter(Context context, List<ItemObjects> itemList) {
        this.itemList = itemList;
        this.context = context;
    }

    @Override
    public SolventViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {

        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.solvent_list, null);
        SolventViewHolders rcv = new SolventViewHolders(layoutView);
        return rcv;
    }

    @Override
    public void onBindViewHolder(SolventViewHolders holder, int position) {
        holder.countryName.setText(itemList.get(position).getName());
        holder.countryPhoto.setImageResource(itemList.get(position).getPhoto());
    }

    @Override
    public int getItemCount() {
        return this.itemList.size();
    }
}

The custom RecyclerView Adapter requires a layout to manager how its View components will appear. The onCreateViewHolder(ViewGroup parent, int viewType)  method of the class inflate a layout that will be used to the RecyclerView UI.

Lets create a layout file in the project layout folder and name this file solvent_list.xml. Add one ImageView and a TextView and set it to align horizontal.

Copy and paste the code as shown below.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/card_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    card_view:cardUseCompatPadding="true"
    card_view:cardCornerRadius="8dp"
    android:layout_marginBottom="16dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/country_photo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/action_settings"
            android:scaleType="centerCrop" />

        <TextView
            android:id="@+id/country_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="13sp"
            android:text="@string/hello_world"
            android:textColor="#ffffff"
            android:layout_below="@+id/country_photo"
            android:paddingBottom="8dp"
            android:paddingTop="8dp"
            android:gravity="center_horizontal"
            android:layout_alignParentBottom="true"
            android:background="#1976D2"/>

    </RelativeLayout>

</android.support.v7.widget.CardView>

The ViewHolder class uses the ViewHolder Pattern and it is use to get a handle for all View in each item of the RecyclerView object.

The code is simple and easy to understand. You can copy and paste the code in your project.

package inducesmile.com.androidstaggeredgridlayoutmanager;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class SolventViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView countryName;
    public ImageView countryPhoto;

    public SolventViewHolders(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        countryName = (TextView) itemView.findViewById(R.id.country_name);
        countryPhoto = (ImageView) itemView.findViewById(R.id.country_photo);
    }

    @Override
    public void onClick(View view) {
        Toast.makeText(view.getContext(), "Clicked Position = " + getPosition(), Toast.LENGTH_SHORT).show();
    }
}

Lets move over to the MainActivity.java file. In this class, we will get a handle for the RecyclerView object. We will go ahead and create an instance of the StaggeredGridLayoutManager and pass it as a parameter to setLayoutManager method of the RecyclerView class.

Create the object of the RecyclerView Adapter class. We will pass the application context and our data source as parameter in setAdapter method of the RecyclerView.

The complete code for the class is as shown.

package inducesmile.com.androidstaggeredgridlayoutmanager;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.Menu;
import android.view.MenuItem;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {

    private StaggeredGridLayoutManager gaggeredGridLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);

        gaggeredGridLayoutManager = new StaggeredGridLayoutManager(3, 1);
        recyclerView.setLayoutManager(gaggeredGridLayoutManager);

        List<ItemObjects> gaggeredList = getListItemData();

        SolventRecyclerViewAdapter rcAdapter = new SolventRecyclerViewAdapter(MainActivity.this, gaggeredList);
        recyclerView.setAdapter(rcAdapter);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private List<ItemObjects> getListItemData(){
        List<ItemObjects> listViewItems = new ArrayList<ItemObjects>();
        listViewItems.add(new ItemObjects("Alkane", R.drawable.one));
        listViewItems.add(new ItemObjects("Ethane", R.drawable.two));
        listViewItems.add(new ItemObjects("Alkyne", R.drawable.three));
        listViewItems.add(new ItemObjects("Benzene", R.drawable.four));
        listViewItems.add(new ItemObjects("Amide", R.drawable.one));
        listViewItems.add(new ItemObjects("Amino Acid", R.drawable.two));
        listViewItems.add(new ItemObjects("Phenol", R.drawable.three));
        listViewItems.add(new ItemObjects("Carbonxylic", R.drawable.four));
        listViewItems.add(new ItemObjects("Nitril", R.drawable.one));
        listViewItems.add(new ItemObjects("Ether", R.drawable.two));
        listViewItems.add(new ItemObjects("Ester", R.drawable.three));
        listViewItems.add(new ItemObjects("Alcohol", R.drawable.four));

        return listViewItems;
    }
}

The private method getListItemData return a object of theList that wraps an entity object that contains data for the ImageView and TextView controls.

Now, when you run your application you will see the interface that looks similar to the sample that was shown earlier on.

You can download the code for this tutorial below. If you are having hard time downloading the tutorials, kindly contact me.

Remember to subscribe with your email so that you will be among the first to receive our new post once it is published

6 Comments

Add a Comment