In this tutorial, I am going to explain to you how we can create a Staggered GridView in Android Application and pass that view to our recycler view. Before we start I think that you have knowledge about RecyclerView and adapter if not then please read this post here:- Working with RecyclerView in Android Application.

If you read my last post then it was very easy to understand, there is only one chance in this post and last post that was LayoutManager in this post I am using StaggeredGridLayoutManager for this. So we can start our code in simple steps.

Step 1. Create a new Android project in Android Studio.

Step 2. Import all required library in build.gradle 

dependencies {
    /..../

    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation("com.squareup.okhttp3:okhttp:4.0.0")
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
}

Step 3. Create two folders inside the project Model and Adapter to hold data and set data in Android Application.

Create a model file inside the model folder

package com.recyclergridview.model;

public class ImageModel {
    int id;
    String url;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getPhotographer() {
        return photographer;
    }

    public void setPhotographer(String photographer) {
        this.photographer = photographer;
    }

    String photographer;
}

Now create Adapter file inside adapter folder

package com.recyclergridview.adapter;

import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.recyclergridview.R;
import com.recyclergridview.model.ImageModel;

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


public class ImagesAdapter extends RecyclerView.Adapter<ImagesAdapter.CustomViewHolder> {

    private List<ImageModel> imageModelsList;
    private Context mContext;
    private Activity act;

    public ImagesAdapter(Context context, ArrayList<ImageModel> imageList, Activity activity) {
        this.imageModelsList = imageList;
        this.mContext = context;
        this.act = activity;
    }

    @Override
    public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(this.mContext).inflate(R.layout.image_item, parent, false);
        CustomViewHolder viewHolder = new CustomViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(CustomViewHolder holder, final int position) {
        final ImageModel get = imageModelsList.get(position);

        holder.photographer.setText(get.getPhotographer());
        final String image = get.getUrl();
        Glide
                .with(this.mContext)
                .load(image)
                .into(holder.image);

    }


    @Override
    public int getItemCount() {
        return (null != imageModelsList ? imageModelsList.size() : 0);
    }


    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    class CustomViewHolder extends RecyclerView.ViewHolder {

        ImageView image;
        TextView photographer;

        public CustomViewHolder(View itemView) {
            super(itemView);
            image = (ImageView) itemView.findViewById(R.id.image);
            photographer = (TextView) itemView.findViewById(R.id.photographer);

        }
    }
}

We also need a view for an adapter in which we can set data

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:background="#fff"
    android:orientation="vertical">

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

    <TextView
        android:id="@+id/photographer"
        android:padding="5dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Step 4. Now open MainActivity class and initialize Model and Adapter class and put data in it from API as show in below code

package com.recyclergridview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;

import com.recyclergridview.adapter.ImagesAdapter;
import com.recyclergridview.model.ImageModel;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    RecyclerView imageList;

    private RecyclerView.LayoutManager layoutManager;
    ImagesAdapter imagesAdapters;
    ArrayList<ImageModel> imageModelArrays;

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

        imageList = (RecyclerView)findViewById(R.id.imageList);
        layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
        imageList.setLayoutManager(layoutManager);

        imageModelArrays = new ArrayList<>();

        imagesAdapters = new ImagesAdapter(MainActivity.this, imageModelArrays, this);
        imageList.setAdapter(imagesAdapters);


        try {
            getImageFromPexels();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void getImageFromPexels() throws IOException {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://api.pexels.com/v1/search?query=work+place&per_page=50&page=1")
                .header("Authorization", "YOUR_API")
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                String mMessage = e.getMessage().toString();
                //Log.w("failure Response", mMessage);
                //call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                final String mMessage = response.body().string();

                MainActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            JSONObject parent = new JSONObject(mMessage);
                            JSONArray photos = parent.getJSONArray("photos");

                            Log.d("resp", "data"+photos);
                            for (int i = 0; i < photos.length(); i++) {

                                JSONObject data = photos.getJSONObject(i);

                                JSONObject imageUrls = data.getJSONObject("src");
                                ImageModel imageModel = new ImageModel();
                                imageModel.setId(data.getInt("id"));
                                imageModel.setPhotographer(data.getString("photographer"));
                                imageModel.setUrl(imageUrls.getString("medium"));

                                imageModelArrays.add(imageModel);
                            }

                            imagesAdapters.notifyDataSetChanged();

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        });
    }
}

And you need to call RecyclerView in activity_main.xml file to display data.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

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

</android.support.constraint.ConstraintLayout>

That’s it hope this above code help you to create Staggered Grid Layout for your Android application.