In my earlier tutorials of RecyclerView we had learn how to use RecyclerView to create ListView and GridView items. Today we are going to create Staggered GridView and Horizontal RecyclerView.
Staggered GridView is nothing but GridView with random grid sizes that look nice in app. To achieve this we need StaggeredGridLayoutManager and the syntax is shown below :
1 |
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); |
Here 2 is the no. of columns that you want in single row.
In earlier android we need to create a custom class for horizontal listview but in latest RecyclerView library we don’t need this thing we can achieve this thing in simple one step :
1 |
recyclerView.setLayoutManager(new LinearLayoutManager(RecyclerView_Activity.this, LinearLayoutManager.HORIZONTAL, false)); |
Here we have to set LinearLayoutManager to HORIZONTAL or VERTICAL according to our need.
In this tutorial, we are going to learn how to use RecyclerView for Staggered GridView and Horizontal ListView.
1. Create a new project in Android Studio by navigating to File ⇒ New Android ⇒ Application Project and fill required details. By default my activity is MainActivity.java.
2. Open build.gradle and include the recyclerview library.
1 2 3 4 5 6 |
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:cardview-v7:23.0.1' compile 'com.android.support:recyclerview-v7:23.0.1' } |
3. For recyclerview create a xml file naming recyclerview.xml and add the following code.
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <!-- Recycler View --> <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recycler_view" android:layout_width="fill_parent" android:layout_height="wrap_content" android:scrollbars="none" /> |
4. Now for recycler view we have to create a custom layout naming item_row.xml and add the following code.
If you want to learn more about recycler view read this tutorial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<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" > <!-- Recycler View Item Row --> <LinearLayout android:layout_width="fill_parent" android:orientation="vertical" android:layout_height="fill_parent"> <ImageView android:id="@+id/image" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerCrop" /> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="14sp" android:textColor="#ffffff" android:paddingBottom="8dp" android:paddingTop="8dp" android:gravity="center" android:background="#FF2259"/> </LinearLayout> </android.support.v7.widget.CardView> |
5. Create a getter and setter class naming Data_Model.java and add the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com.androidstaggeredgridlayoutmanager_demo; /** * Created by SONU on 25/09/15. */ public class Data_Model { // Getter and Setter model for recycler view items private String title; private int image; public Data_Model(String title, int image) { this.title = title; this.image = image; } public String getTitle() { return title; } public int getImage() { return image; } } |
6. Now create ViewHolder class naming RecyclerViewHolder.java and add the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.androidstaggeredgridlayoutmanager_demo; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ImageView; import android.widget.TextView; /** * Created by SONU on 25/09/15. */ public class RecyclerViewHolder extends RecyclerView.ViewHolder { // View holder for gridview recycler view as we used in listview public TextView title; public ImageView imageview; public RecyclerViewHolder(View view) { super(view); // Find all views ids this.title = (TextView) view .findViewById(R.id.title); this.imageview = (ImageView) view .findViewById(R.id.image); } } |
7. Now create a adapter class for recyclerview naming RecyclerView_Adapter.java and add the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
package com.androidstaggeredgridlayoutmanager_demo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.ViewGroup; import java.util.ArrayList; /** * Created by SONU on 25/09/15. */ public class RecyclerView_Adapter extends RecyclerView.Adapter<RecyclerViewHolder> {// Recyclerview will extend to // recyclerview adapter private ArrayList<Data_Model> arrayList; private Context context; public RecyclerView_Adapter(Context context, ArrayList<Data_Model> arrayList) { this.context = context; this.arrayList = arrayList; } @Override public int getItemCount() { return (null != arrayList ? arrayList.size() : 0); } @Override public void onBindViewHolder(RecyclerViewHolder holder, int position) { final Data_Model model = arrayList.get(position); RecyclerViewHolder mainHolder = (RecyclerViewHolder) holder;// holder Bitmap image = BitmapFactory.decodeResource(context.getResources(), model.getImage());// This will convert drawbale image into // bitmap // setting title mainHolder.title.setText(model.getTitle()); mainHolder.imageview.setImageBitmap(image); } @Override public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // This method will inflate the custom layout and return as viewholder LayoutInflater mInflater = LayoutInflater.from(viewGroup.getContext()); ViewGroup mainGroup = (ViewGroup) mInflater.inflate( R.layout.item_row, viewGroup, false); RecyclerViewHolder listHolder = new RecyclerViewHolder(mainGroup); return listHolder; } } |
8. Now create a new layout xml file naming activity_main.xml and add the following code. In this i am using two buttons for Staggered gridview and horizontal recyclerview.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<LinearLayout android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:gravity="center" android:orientation="vertical" > <!-- Two Buttons to Open different recycler view --> <Button android:text="@string/staggeredgrid" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/staggeredRecyclerViewBtn" android:gravity="center" android:padding="10dp" android:textSize="17sp" android:textColor="#000000"/> <Button android:text="@string/horizontalrecyclerview" android:layout_wi dth="fill_parent" android:layout_height="wrap_content" android:id="@+id/horizontalRecyclerViewBtn" android:gravity="center" android:textSize="17sp" android:padding="10dp" android:textColor="#000000"/> </LinearLayout> |
9. Open your MainActivity.java and add the following code. In this code a new activity opens on both button click and a data is pass via intent to next activity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.androidstaggeredgridlayoutmanager_demo; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private static Button staggeredRecyclerView, horizontalRecyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); staggeredRecyclerView = (Button)findViewById(R.id.staggeredRecyclerViewBtn); horizontalRecyclerView = (Button)findViewById(R.id.horizontalRecyclerViewBtn); staggeredRecyclerView.setOnClickListener(this); horizontalRecyclerView.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.staggeredRecyclerViewBtn: OpenRecyclerViewActivity("staggered"); break; case R.id.horizontalRecyclerViewBtn: OpenRecyclerViewActivity("horizontal"); break; } } //Open Recycler View activity and pass a string to notify which recyclerview is to setup private void OpenRecyclerViewActivity(String navigateFrom){ Intent in = new Intent(MainActivity.this, RecyclerView_Activity.class); in.putExtra("navigateFrom",navigateFrom); startActivity(in); } } |
10. In above we are opening new activity so we need to create a new activity naming RecyclerView_Activity.java and add the following code. In this code we get the intent data and according to that intent data we display the recyclerview i.e horizontal or staggered.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
package com.androidstaggeredgridlayoutmanager_demo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.MenuItem; import java.util.ArrayList; /** * Created by SONU on 25/09/15. */ public class RecyclerView_Activity extends AppCompatActivity { private static RecyclerView recyclerView; //String and Integer array for Recycler View Items public static final String[] TITLES= {"Hood","Full Sleeve Shirt","Shirt","Jean Jacket","Jacket"}; public static final Integer[] IMAGES= {R.drawable.one,R.drawable.two,R.drawable.three,R.drawable.four,R.drawable.five,}; private static String navigateFrom;//String to get Intent Value @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.recyclerview); initViews(); populatRecyclerView(); } // Initialize the view private void initViews() { getSupportActionBar().setDisplayHomeAsUpEnabled(true);//Set Back Icon on Activity navigateFrom = getIntent().getStringExtra("navigateFrom");//Get Intent Value in String recyclerView = (RecyclerView) findViewById(R.id.recycler_view); recyclerView.setHasFixedSize(true); //Set RecyclerView type according to intent value if (navigateFrom.equals("horizontal")) { getSupportActionBar().setTitle("Horizontal Recycler View"); recyclerView .setLayoutManager(new LinearLayoutManager(RecyclerView_Activity.this, LinearLayoutManager.HORIZONTAL, false)); } else { getSupportActionBar().setTitle("Staggered GridLayout Manager"); recyclerView .setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));// Here 2 is no. of columns to be displayed } } // populate the list view by adding data to arraylist private void populatRecyclerView() { ArrayList<Data_Model> arrayList = new ArrayList<>(); for (int i = 0; i < TITLES.length; i++) { arrayList.add(new Data_Model(TITLES[i],IMAGES[i])); } RecyclerView_Adapter adapter = new RecyclerView_Adapter(RecyclerView_Activity.this, arrayList); recyclerView.setAdapter(adapter);// set adapter on recyclerview adapter.notifyDataSetChanged();// Notify the adapter } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()){ case android.R.id.home: finish(); break; } return super.onOptionsItemSelected(item); } } |
11. Finally add the second activity i.e. RecyclerView_Activity to your Manifest file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.androidstaggeredgridlayoutmanager_demo" > <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".RecyclerView_Activity" /> </application> </manifest> |
12. Now, you are all done, run your app and you will get the output as shown in video.
Thanks.
Subscribe to us and get the latest news.
17 Comments
Shanaka Perera
Saturday, February 27th, 2016Good tutorial..
jackbear
Tuesday, March 15th, 2016if i want to use URL as an image, what should i do?
Droid
Tuesday, March 15th, 2016Hi JackBear,
For image url you can use Glide, Picasso or Universal Image Loader libraries for loading URL over imageViews. Just google about this Libraries and they are easy to use. You can check one of my tutorial about Universal Image Loader.
Thanks
jackbear
Wednesday, March 16th, 2016thank you, i use picasso and change the image parameter to string and change the adapter using picasso, it works 😀
now for the next part, if i want to use onclicklistener to each of the item in recyclerview, what should i do? o.o
Droid
Wednesday, March 16th, 2016Hi,
I had given one RecyclerView link at the start of this tutorial. Open that url you will get to know how to implement onClickListener over RecyclerView.
renilia
Thursday, April 7th, 2016Great tutorial, thanks !!!
donny
Saturday, October 1st, 2016how to make width of card view to half screen or fourth screen
Dr. Droid
Saturday, October 1st, 2016Hi Donny,
For cardview width half of the screen you need to use GridLayoutManager and set COULMN SPAN to 2. By doing this only 2 CardView will be displayed.
Thanks
obbserv
Thursday, December 22nd, 2016Getting grid layout instead of staggered grid layout.
Anyone??
Dr. Droid
Thursday, December 22nd, 2016Hi Obbserv,
You can use GridLayoutManager instead of StaggeredGridLayout and for this you need to fix the height of your CardView.
Thanks
hp
Wednesday, February 1st, 2017How to make this auto scroll?
Dr. Droid
Wednesday, February 1st, 2017Hi HP,
You can use below code for this:
recyclerView.post(new Runnable() {
@Override
public void run() {
// Call smooth scroll
recyclerView.smoothScrollToPosition(adapter.getItemCount());
}
});
Thanks
Shonali
Tuesday, March 7th, 2017Very useful.
Sam
Sunday, August 27th, 2017Great example. But in my case it is producing same height of all items in recyclerview.
Dr. Droid
Sunday, August 27th, 2017Hi Sam,
It might be as you are not putting height of your image view wrap content or all of your Images are of same size.
Thank
Shan@88
Thursday, October 26th, 2017Hi,
When you move your cursor over a particular item, the item gets highlighted, (I am not sure if highlighted is the right word to be used here). However I see that there is no onClick method implemented. Could you please tell how this is handled?
Dr. Droid
Thursday, October 26th, 2017Hi Shan@88,
The above article is about how to implement staggered RecyclerView. I have not shown how to implement click event on items.
To know how to implement click event on items please see this article : https://www.androhub.com/android-recyclerview/
Thanks