Implement RecyclerView in my way (a little bit advance)
Study is a process which makes you have to keep doing this every day as a habit. Recently, I have been learning a lot from my senior developers in my team. And the technique below is one of the most interesting things that they showed me.
Okay, RecyclerView is very very popular for all android developers. If you don’t know what it is. Don’t worry, read this for the definition. After reading it, still hard to understand (I know that feeling) then try doing this tutorial by yourself (I strongly recommend you not to copy and paste the code but reading and doing step by step by yourself).
As you can see in the example above. The author created an adapter for the RecyclerView called MoviesAdapter. This adapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> . Inside the adapter you can easily find MyViewHolder class. This is the simplest and easiest way. I used to do this, too. I spend many times to practice this and can easily code all those things in few minutes. But when you working with multiple viewTypes (which i will introduce in the next post), you have to create multiple ViewHolder class in one adapter class. For example, you have a screen which needs 10–12 viewTypes for the RecyclerView. Your job is to write 10–12 ViewHolder class in one adapter and then use recyclerView.setAdapter(adapter) to display the data on the screen. And imagine each ViewHolder contains 10–15 views, and for each view you must do findViewById() or BindView() if you use ButterKnife. Your adapter now becomes a big big pool to contain all of those ViewHolders and their childs.
This is not good for you and for all those who gonna read and maintain your code. That’s why you need to think and come up with a new way to optimize your code. Using the reusability of Java. I’m gonna show you my way.
Basically, you will need 5 steps for this:
- Create an interface and name it Item
- Create an abstract class ItemBaseViewHolder
- Create an abstract class ItemBaseAdapter
- Create your adapter and viewholder
- Create your model object and implements Item
Let’s get into each step in details:
Step 1: Create an interface Item
Normally, you don’t need to declare any methods in this interface (in some cases you will need to declare methods). Each object model must implements this interface. This interface plays a role to join all of your object model in the same adapter. When working with viewType, you just need a for loop through your data list to check instance of to bring this item to the specific viewType that you want.
Step 2: Create an abstract class ItemBaseViewHolder
This class is a parent ViewHolder for all of your child view holders in your application. <T extends Item>. T is generic type and could be any of your object model (for example: Movies, Videos, News, etc). The constructor ItemBaseViewHolder contains 2 parameters: ViewGroup parent is the RecyclerView (meanwhile itemView is the root layout of your child item) and int resId is your child item layout (R.layout.child_item). You may not need the getItem() method, but public void bindData(@Nullable T item) is really important (I will explain more details in Step 4)
Step 3: Create an abstract class ItemBaseAdapter
Just like the ItemBaseViewHolder. This class is a parent class for all of your adapters (you may remove the abstract keyword if you want to). We need an attribute in this class, obviously it must be a List. The bindData method will called here. As I explained, a List<Item> contains many type of objects, but those objects must have implemented the interface Item. Base on the position of each item in the List, we surely know the “instance of” this item and then bind it into the respective viewholder.
Step 4: Create your child adapter and viewholder
When your child viewholder extends from the parent viewholder (ItemBaseViewHolder), it forces you to override the constructor. Just override it and do the findViewById in this constructor. If you use ButterKnife you can do as the way i did. I guess you will understand the responsibility of the bindData() by looking at my code. Just like its name, you do everything with your views in this function (setText, setImageResource, etc). If you watch carefully, you will find out the type you put right after the ItemBaseViewHolder<//here> will be the type of the parameter of the bindData(//here too). That explain for the <T extends Item>. If you are confused why the Item is an interface but T extends Item instead of implements Item. The answer is here. Also i suggest you should read more about the Java generic. That’s for our child viewholder class.
Surprised? Just only this, all you need is to override the onCreateViewHolder, return new instance of your child viewholder and pass your child layout into it. If you are working with multiple viewTypes, then this is the place where you override this method.
And the method getItemAt(int position) will be called here to check for the instance of.
Step 5: Create your object model
This is the final step, after you create your model, go to your MainActivity (or WhateverActivity) to set up your adapter.
I will explain why i use the set method instead of passing the itemList in the constructor of the adapter. When you are working with API, your data will be fetched every second. What if your internet connection is slow, your data can not load properly, meanwhile you pass your itemList in the constructor and display them right away. In this case, nothing will be displayed. By using set method we can handle this problem, we will show the progress bar, if the data fully loaded, we set it into the adapter then hide the progress bar and display it.
That’s it, if you have any questions please leave them in the comment below, i will try to answer it. Thank you for reading.