Android Tutorials - Recyclerview and its On Item click listener - Part 1

  • By :Subba Raju
  • Date : 15-02-2017

Lists are an inevitable part of life in the technology driven world. Facebook, Instagram, your music app, and your news feed on your phone,everything is a list. After all they are considered to be one of the most convenient ways of displaying data ever since.

But for an android developer, lists can sometimes get quite unnerving because of its resource consumption which can potentially slow down the app or make it crash-prone. That is when Google released RecyclerView, the master behind the idea of using a reuse pattern to create views just once and recycle them when needed.

In this 2 part tutorial, I'm going to walk you through recyclerview, its advantages over listview, and also discuss about how to create an on item click listener with recyclerview.

When Android released LOLLIPOP(5.0), RecyclerView was implemented instead of the ListView. As Android developers, based on requirement and what really needs to be implemented, we can choose either of the two, as ListView and Recyclerview are the two most popular methods.

Let us get to know a few things first,

  • What is ListView
  • Pros and Cons of ListView
  • What is RecyclerView
  • Pros and Cons of RecyclerView

ListView

List View is a view group that displays a list of scrollable items. The list items are automatically inserted to the list using an Adapter that pulls content from a source such as an array or database query and converts each item result into a view that's placed into the list

ListView is a good widget which is included in Android SDK until Android Kitkat. It only allows to create vertical listview for a smooth scrolling. However, in order to  handle the list, such as to configure it in some way, the only way to do this is through the ListView object or inside the adapter. And the only way to implement the Listview is through Listview object or by creating an adapter.

ViewHolder is used to store Object, each component view inside layout, with a class to hold our set of Views. As the ViewHolder is not available by default, we create it explicitly inside getView() method.

Pros of ListView:

  • Its very easy to use
  • Listview has Default Adapter
  • OnItemClickListener is available in Listview

Cons of ListView:

  • ListView provides only one type of view i.e Vertical ListView, and there is no way to implement the others such as Horizontal ListView, GridView etc.

RecyclerView:

RecyclerView, with faster performance, is the advanced version of ListView which can be used to implement Vertical List, Horizontal List and Gridview with the help of Layout Managers.

RecyclerView has different components to display our data. They provide an abstract class and our app needs to extend it.

Pros of RecyclerView:

ViewHolder Pattern:

While the ViewHolder Pattern is recommended, but never a compulsion in the ListView, it is  mandatory in the case of  RecyclerView by using RecyclerView.ViewHolder class.

    LayoutManager: 
    i)LinearLayoutManager - It supports both vertical and horizontal list,
    ii)GridLayoutManager - It support to display grid view like Gallery.
    And the best thing is that all of these can be done Dynamically.

    Item Animator:
    Using the RecyclerView.ItemAnimator class: Used to animate the views.

    Item Decoration:

    RecyclerView.ItemDecorator class: Used to create dividers and grouping boundaries(Horizontal, vertical) etc.

    Cons of RecyclerView

    1. Comparatively complex in nature.
    2. It can take a lot of time for a beginner to understand a RecyclerView fully.
    3. No default OnItemClicklistener.

    In this tutorial we are going to learn how to implement recyclerview, adapter class, Vertical , Horizontal, Grid and onItemClickListener by creating an interface.

    Let's Start with Example of Recyclerview and Item click listener

    RecyclerView (Vertical Scroll):

    1.Create new Android Project.

    2. To achieve recyclerview we need to implement support.design in build.gradle file.

    To achieve recyclerview

      3.Create layout activity_main.xml file in which we should implement Recyclerview

      To achieve recyclerview

      4. Here is a look at the Preview

      To achieve recyclerview

        5.Now Create Activity class MainActivity.class ,  In this class declare Recyclerview and android id

        To achieve recyclerview
        LayoutManager.Vertical displays the list vertically

          Now create Layout manager to set the recyclerview to horizontal, vertical, grid etc.

            To achieve recyclerview
            LayoutManager.Horizontal displays the list horizontally.

                Before setting data, for each recyclerview there is an adapter class to hold one row or column.

                Now let us set data in the recyclerview with a list.

                Create MainModel.java class
                 

                public class MainModel {
                  private String offerName;
                  private int offerIcon;
                  public String getOfferName() {
                      return offerName;
                  }
                  public void setOfferName(String offerName) {
                      this.offerName = offerName;
                  }
                  public int getOfferIcon() {
                      return offerIcon;
                  }
                  public void setOfferIcon(int offerIcon) {
                      this.offerIcon = offerIcon;
                  }
                
                Now in the Main Activity Class
                
                final ArrayList<MainModel> mainModelArrayList = prepareList();
                final MainRecyclerAdapter mainRecyclerAdapter = new MainRecyclerAdapter(this,mainModelArrayList);
                mainRecyclerView.setAdapter(mainRecyclerAdapter);
                
                private ArrayList<MainModel> prepareList() {
                  ArrayList<MainModel> mainModelList = new ArrayList<>();
                  for (int i = 0; i < categoryName.length; i++) {
                      MainModel mainModel = new MainModel();
                      mainModel.setOfferName(categoryName[i]);
                      mainModel.setOfferIcon(categoryIcon[i]);
                      mainModelList.add(mainModel);
                  }
                  return mainModelList;
                }

                Now set the adapter for recyclerview by calling:

                mainRecyclerView.setAdapter(mainRecyclerAdapter);
                

                Now the Adapter class will be extended to RecyclerView.Adapter

                This adapter class is an Abstract static class which overrides 3 methods, which are,onCreateViewHolder (), onBindViewHolder(), getItemCount().

                In the adapter class we have a xml file to hold one single row.

                Now Create layout row_main_adapter.xml file
                 

                <?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:orientation="vertical">
                  <LinearLayout
                      android:id="@+id/row_main_adapter_linear_layout"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_margin="5dp"
                      android:orientation="horizontal">
                
                      <ImageView
                          android:id="@+id/row_main_adapter_iv"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          android:scaleType="center"
                          android:contentDescription="@null"
                          android:src="@mipmap/ic_launcher" />
                
                      <TextView
                          android:id="@+id/row_main_adapter_tv"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          android:layout_gravity="center"
                          android:layout_marginStart="10dp"
                          android:textSize="14sp"/>
                  </LinearLayout>
                
                  <View
                      android:layout_width="match_parent"
                      android:layout_height="0.5dp"
                      android:layout_marginTop="5dp"
                      android:background="@color/colorPrimary"/>
                </LinearLayout>

                Here is a look at the Preview

                RecyclerView

                onCreateViewHolder() :  only creates a new viewholder when there are no existing view holders which the RecyclerView can reuse.

                onBindViewHolder()  : It is Called by RecyclerView to display the data at the specified position

                getItemCount() : This method should return the number of list items.

                Implementing onItemClickListener :

                To Implement Recyclerview onItemClickListener, an interface should be created which specifies listener’s behaviour, similar to normal click listener except the fact  that it also has the position as parameter

                Create Interface OnRecyclerViewItemClickListener

                import android.view.View;
                public interface OnRecyclerViewItemClickListener {
                  void onItemClick(int position, View view);
                }

                With this Interface we can implement in Activity or fragment. This will Override the itemclick method in activity class.

                mainRecyclerAdapter.setOnRecyclerViewItemClickListener(this);

                Before setting the adapter, set the itemclick listener.

                In Adapter class, this is how the initialization should look like,

                private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener;
                public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener onRecyclerViewItemClickListener) {
                  this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;
                }
                Up next, in View holder method, declare the layout setOnclicklistener in this manner.
                rowMainParentLinearLayout.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      if (onRecyclerViewItemClickListener != null) {
                          onRecyclerViewItemClickListener.onItemClick(getAdapterPosition(), view);
                      }
                  }
                });

                Here, set view itself as a click listener and call interface with proper position

                Finally Adapter class looks like:

                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.LinearLayout;
                import android.widget.TextView;
                import java.util.ArrayList;
                public class MainRecyclerAdapter extends RecyclerView.Adapter<MainRecyclerAdapter.ViewHolder>{
                  private ArrayList<MainModel> mainModelArrayList;
                  private Context context;
                  private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener;
                  public MainRecyclerAdapter(Context context,ArrayList<MainModel> mainModelArrayList) {
                      this.context = context;
                      this.mainModelArrayList = mainModelArrayList;
                  }
                  @Override
                  public MainRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
                      View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_main_adapter, viewGroup, false);
                      return new MainRecyclerAdapter.ViewHolder(view);
                  }
                  @Override
                  public void onBindViewHolder(MainRecyclerAdapter.ViewHolder viewHolder, int position) {
                      final MainModel offersListModel = mainModelArrayList.get(position);
                      viewHolder.rowMainText.setText(offersListModel.getOfferName());
                      viewHolder.rowMainImage.setImageResource(offersListModel.getOfferIcon());
                   viewHolder.rowMainParentLinearLayout.setTag(offersListModel);
                  }
                  @Override
                  public int getItemCount() {
                      return mainModelArrayList.size();
                  }
                  public class ViewHolder extends RecyclerView.ViewHolder{
                      private ImageView rowMainImage;
                      private TextView rowMainText;
                      private LinearLayout rowMainParentLinearLayout;
                      public ViewHolder(View view) {
                          super(view);
                          rowMainImage = view.findViewById(R.id.row_main_adapter_iv);
                          rowMainText = view.findViewById(R.id.row_main_adapter_tv);
                          rowMainParentLinearLayout =  view.findViewById(R.id.row_main_adapter_linear_layout);
                          rowMainParentLinearLayout.setOnClickListener(new View.OnClickListener() {
                              @Override
                              public void onClick(View view) {
                                  if (onRecyclerViewItemClickListener != null) {
                                      onRecyclerViewItemClickListener.onItemClick(getAdapterPosition(), view);
                                  }
                              }
                          });
                      }
                  }
                  public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener onRecyclerViewItemClickListener) {
                      this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;
                  }
                }
                

                To get the clicked item and its position:

                Set tag to layout in adapter class, and get that tag in activity class.

                In Adapter class:

                @Override
                public void onItemClick(int position, View view) {
                  MainModel mainModel = (MainModel) view.getTag();
                  switch (view.getId()) {
                      case R.id.row_main_adapter_linear_layout:
                          Toast.makeText(this,"Position clicked: " + String.valueOf(position) + ", "+ mainModel.getOfferName(),Toast.LENGTH_LONG).show();
                          break;
                  }
                }

                Final Activity Class will be:

                import android.os.Bundle;
                import android.support.v7.app.AppCompatActivity;
                import android.support.v7.widget.LinearLayoutManager;
                import android.support.v7.widget.RecyclerView;
                import android.view.View;
                import android.widget.Toast;
                
                import java.util.ArrayList;
                
                public class MainActivity extends AppCompatActivity implements OnRecyclerViewItemClickListener{
                
                  private final int categoryIcon[] = {
                          R.drawable.ic_launcher,
                          R.drawable.ic_launcher,
                          R.drawable.ic_launcher,
                          R.drawable.ic_launcher,
                          R.drawable.ic_launcher,
                          R.drawable.ic_launcher,
                          R.drawable.ic_launcher,
                          R.drawable.ic_launcher,
                          R.drawable.ic_launcher
                  };
                
                  private final String categoryName[] = {
                          "Apple",
                          "Samsung",
                          "MI",
                          "Motorola",
                          "Nokia",
                          "Oppo",
                          "Micromax",
                          "Honor",
                          "Lenovo"
                  };
                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      setContentView(R.layout.activity_main);
                      final RecyclerView mainRecyclerView = findViewById(R.id.activity_main_rv);
                      final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,
                              LinearLayoutManager.VERTICAL, false);
                      mainRecyclerView.setLayoutManager(linearLayoutManager);
                      //Recycler Adapter
                      final ArrayList<MainModel> mainModelArrayList = prepareList();
                      final MainRecyclerAdapter mainRecyclerAdapter = new MainRecyclerAdapter(this,mainModelArrayList);
                      mainRecyclerAdapter.setOnRecyclerViewItemClickListener(this);
                      mainRecyclerView.setAdapter(mainRecyclerAdapter);
                  }
                  private ArrayList<MainModel> prepareList() {
                      ArrayList<MainModel> mainModelList = new ArrayList<>();
                      for (int i = 0; i < categoryName.length; i++) {
                          MainModel mainModel = new MainModel();
                          mainModel.setOfferName(categoryName[i]);
                          mainModel.setOfferIcon(categoryIcon[i]);
                          mainModelList.add(mainModel);
                      }
                return mainModelList;
                  }
                  @Override
                  public void onItemClick(int position, View view) {
                      MainModel mainModel = (MainModel) view.getTag();
                      switch (view.getId()) {
                          case R.id.row_main_adapter_linear_layout:
                              Toast.makeText(this,"Position clicked: " + String.valueOf(position) + ", "+ mainModel.getOfferName(),Toast.LENGTH_LONG).show();
                              break;
                      }
                  }

                The emulator output will look like:

                In Activity class

                In Activity class

                part 2

                Subscribe For Our Newsletter And Stay Updated

                Recent blogs

                Drupal Blockchain
                There is a new Birdman in the town! An idea that has gripped the biggest institutions in the market. A technology, that...
                Android Development
                In the Android world, I'm sure there is nobody who has not heard of Java. A powerful programming language that can build...
                Drupal AMP
                AMP loads about twice as fast as a normal comparable mobile page and the latency is as less as one-tenth. Intended to provide the...

                This website uses cookies to offer you an enhanced website experience. We collect information about how you interact with our website to provide personalized services to you. To find out more, see our Privacy Policy

                ×