Developing app is amazing. It is that inner feeling that when something is missing or it is not how you want it, then you can simply create your own. And create Android applications is never been that easy. With this new Android Development series, we are going to teach you what you need to be able to make your dream app on your own. In today’s article, we are going to talk about RecyclerView.

 

Basically, the RecyclerView widget is a more advanced and flexible version of ListView. If you need to display a list of items/ emails/data, as it is often the case in mobile applications, you need to be able to handle this widget.

QUICK CODE

Here you are all the code that you need to develop your first RecyclerView

RecyclerViewTutorial on Github

FULL TUTORIAL

First of all, we need to add the dependency in the build.gradle file to import the RecyclerView in our project.

implementation 'com.android.support:recyclerview-v7:+'

 

 

The first step is to create the Activity that will host our RecyclerView, I have called it ‘MainActivity’.

File > New > Activity > Empty Activity

Empty Activity

We need to add the RecyclerView to our activity_main.xml file. We set the width and height to match_parent since we want the view to cover the whole screen. Then we also give it an ID of rv_list, where RV stays for RecyclerView.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:id="@+id/rv_list">
</android.support.v7.widget.RecyclerView>

 

Then we create a new layout file.

layout > New > Layout resource file

Create Layout

Every single item of our list will be inflated from this layout file. I have designed a simple layout with one ImageView and two TextViews.

List Item Layout

<?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="wrap_content"
   android:padding="16dp">

   <ImageView
       android:id="@+id/iv_icon"
       android:layout_width="56dp"
       android:layout_height="56dp"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent"
       app:srcCompat="@android:drawable/ic_lock_lock" />

   <TextView
       android:id="@+id/tv_title"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginLeft="8dp"
       android:layout_marginStart="8dp"
       android:text="Main Title"
       android:textColor="#333"
       android:textSize="24sp"
       app:layout_constraintStart_toEndOf="@+id/iv_icon"
       app:layout_constraintTop_toTopOf="@+id/iv_icon" />

   <TextView
       android:id="@+id/tv_subtitle"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Subtitle"
       app:layout_constraintStart_toStartOf="@+id/tv_title"
       app:layout_constraintTop_toBottomOf="@+id/tv_title" />
  
</android.support.constraint.ConstraintLayout>

 

 

Our RecyclerView must have an Adapter, which will be responsible to create our views in the list and bind the data inside our list item. So, we create a new Class, I called it RvAdapter.

app > New > Java Class

New Java Class

Inside the class we just create we need another new class, call it RecyclerViewHolder, which must extend RecyclerView.ViewHolder. This class will be handling our UI components and it will bind the data from our data source into them.

class RecyclerViewHolder extends RecyclerView.ViewHolder

 

We create the class constructor and we also create three new variables which represent our two TextViews and our ImageView.

TextView mTitleTextView;
TextView mSubtitleTextView;
ImageView mIconImageView;
public RecyclerViewHolder(@NonNull View itemView) {
   super(itemView);
}

 

In our constructor, we need to find each View inside our list items by ID from the itemView that the function takes as parameters from the Adapter.

mTitleTextView = itemView.findViewById(R.id.tv_title);
mSubtitleTextView = itemView.findViewById(R.id.tv_subtitle);
mIconImageView = itemView.findViewById(R.id.iv_icon);

 

We also create a new function called bind that we will use to change the text inside of our TextViews.

void bind(int listIndex) {
   mTitleTextView.setText("Add Title Here");
   mSubtitleTextView.setText("Add Subtitle Here");
}

 

We are ready to work on our Adapter class. We start with a new variable which will contain the number of items in our list, and then we initialize its value through the class constructor.

private int mNumberItems;

public RvAdapter(int numberItems) {
   numberItems = mNumberItems;
}

 

Our RvAdapter class must extend the RvAdapter.RecyclerViewHolder class we created before.

public class RvAdapter extends RecyclerView.Adapter<RvAdapter.RecyclerViewHolder>

 

Android Studio will ask us to override the core functions of our Adapter, which are onCreateViewHolder, onBindViewHolder, and getItemCount.

@NonNull
@Override
public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
   return null;
}

@Override
public void onBindViewHolder(@NonNull RecyclerViewHolder recyclerViewHolder, int position) {

}

@Override
public int getItemCount() {
   return 0;
}

 

 

In the onCreateViewHolder is where the magic appends. From here we are going to inflate the item layout we created. We get the context from the main viewGroup component, we call LayoutInflater to get our layout source file and then we add the item layout to the RecyclerView through the method inflate. Then we create a new RecyclerViewHolder object and pass the view we inflated to the RecyclerViewHolder class, which will find the views inside the layout and then bind the values inside our TextViews.

public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
   Context context = viewGroup.getContext();
   int layoutIdListItem = R.layout.list_item;

   LayoutInflater inflater = LayoutInflater.from(context);

   boolean attachToParentImmediately = false;

   View view = inflater.inflate(layoutIdListItem, viewGroup, attachToParentImmediately);
   RecyclerViewHolder viewHolder = new RecyclerViewHolder(view);

   return viewHolder;
}

 

The method onBindViewHolder will simply call the RecyclerViewHolder bind function that will then set the text of our TextViews. The method getItemCount will just return the mNumberItems which contains the number of items in the list.

@Override
public void onBindViewHolder(@NonNull RecyclerViewHolder recyclerViewHolder, int position) {
   recyclerViewHolder.bind(position);
}
@Override
public int getItemCount() {
   return mNumberItems;
}

 

We are done with our Adapter class. Now we need to attach the Adapter to our RecyclerView through our MainActivity class. We start by instantiating three new variables: the number of items in our list, our Adapter object, and the RecyclerView itself.

private static final int NUM_OF_ITEMS = 100;
private RvAdapter adapter;
private RecyclerView recyclerView;

 

For our RecyclerView, we are going to use a LinearLayoutManager, which will enable us to create a vertical scrolling list. We find our RecyclerView in the layout by its ID. Then we create our LinearLayoutManager object and we attach it to our RecyclerView.

recyclerView = findViewById(R.id.rv_list);

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);

 

And finally, we attach our Adapter to the RecyclerView. We also setHasFixedSize of the RecyclerView to true for performances purposes.

recyclerViewr .setHasFixedSize(true);
adapter = new RvAdapter(NUM_OF_ITEMS);
recyclerView.setAdapter(adapter);

 

ONCLICK

To handle the onClick on the RecyclerView we need to add some more code. First of all, we create a ListItemClickListener interface with a onListItemClick function inside our RvAdapter class.

public interface ListItemClickListener {
   void onListItemClick(int clickedIndex);
}

 

Then we create a ListItemClickListener object variable and we pass it to the RvAdapter constructor.

final private ListItemClickListener mOnClickListener;

public RvAdapter(int numberItems, ListItemClickListener clickListener) {
   mNumberItems = numberItems;
   mOnClickListener = clickListener;
}

 

Our RecyclerViewHolder must implement the View.OnClickListener to detect the onClick input through the onClick method that we add to the class.

class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
	@Override
public void onClick(View view) {
   int clickedPosition = getAdapterPosition();
   mOnClickListener.onListItemClick(clickedPosition);
}

 

We also call the setOnClickListener method in the constructor.

public RecyclerViewHolder(@NonNull View itemView) {
   super(itemView);

   mTitleTextView = itemView.findViewById(R.id.tv_title);
   mSubtitleTextView = itemView.findViewById(R.id.tv_subtitle);
   mIconImageView = itemView.findViewById(R.id.iv_icon);

   itemView.setOnClickListener(this);
}

 

We are almost done. Our MainActivity class needs to implement the interface we previously created.

public class RecyclerViewTutorial extends AppCompatActivity implements RvAdapter.ListItemClickListener

 

Finally, we need to override the onListItemClick method that will be called every time we touch an item in our RecyclerView. We also need to pass this when we create our Adapter object since we changed its constructor.

adapter = new RvAdapter(NUM_OF_ITEMS, this);

	private Toast mToast;

@Override
public void onListItemClick(int clickedIndex) {
   if (mToast != null) mToast.cancel();
   mToast = new Toast(this);
   mToast = Toast.makeText(this, "List Item #" + clickedIndex, Toast.LENGTH_SHORT);
  
   mToast.show();
}

List Complete

 

DELETING LIST ITEM ONCLICK

The RecyclerView widget is pretty powerful. For example, to remove a list item from the list dynamically on click we just need to add a few more lines of code.

@Override
public void onListItemClick(int clickedIndex) {
   if (mToast != null) mToast.cancel();

   mToast = new Toast(this);
   mToast = Toast.makeText(this, "Removed Item #" + clickedIndex, Toast.LENGTH_SHORT);

   mToast.show();
   removeAt(clickedIndex);
}

private void removeAt(int position) {
   adapter.notifyItemRemoved(position);
}

 

 

Now we have a basic RecyclerView in our app. From here we can implement many new features just like the remove element function we just show you. Feel free to experiment and uncover all the amazing potential that the RecyclerView has to offer.

GridLayoutManager Example

You can find the whole project on Github. The code is free and open source.

RecyclerViewTutorial on Github

 

See you on the next Android Development tutorial.