In this chapter of the BMI Calculator application tutorial we are going to start using the RecyclerView, what we have already added to the bmis_fragment.xml file.
In this chapter first, we will create an Adapter and a ViewHolder, which won’t have a difficult layout. Thenafter we will create a Data Binding Adapter, which will send the items for the RecyclerView.
The starter project for this lecture is available on GitHub. Just download it using the below link.
After the download, extract the app from the .ZIP file and import it in Android Studio (File -> New -> Import Project…)
Step 1 - Create the layout for the item
Our first task in this chapter is to create a new layout file for the items of the ReceyclerView.
So, go to the res->layout folder, click on it with the right mouse button, select the “New”, then the “Layout Resource File” option. In the popup window name the file as “item_bmi”.
In this layout we gonna use Data Binding also. So, move your mouse to the root view (ConstraintLayout), and press Alt+Enter on Windows or Control/Option+Enter on Mac. This will open up a quick menu, the Show Context Actions menu. There, select to first option, which is “Convert to data binding layout”. Now the layout should look like below.
layout of item using Data Binding
Variables of the layout
In the layout file we can define variables as well. In our case we gonna have 2 variables. One will hold the data of one BMI item, the second one will be the instance of the BmisViewModel::class.
The below variables go into the tags.
Be careful with the package path of the above variables, because the packages have to be raplaced with your project’s package.
The Views of the layout
Next, we gonna implement the Views of the layout, which means we gonna modify the content of the ConstraintLayout.
It is very simple, so we won’t go into the details of it. If you have questions, then leave a comment below. 😊
So, just copy and paste the below views into the ConstraintLayout.
The views of the item
Next is to bind the data with the above created bmi variable.
So, copy and paste the below attributes to the corresponding views.
These lines should be already known by you, because we have used them already in the result_fragment.xml file.
Later we will come back to handle the clicks, but for now we are done.
Step 2 - Binding Adapter for the View
In the last step we have added the setBmiStateColor to the View, but still it won’t work, because we have to define this BindingAdapter for the View . So, open up the DataBindingAdapter from the utils package and paste there the below function.
Step 3 - Create the adapter
Our third task in this chapter is to create the adapter for the RecyclerView. It means, we gonna create a new file, which file will contain the Adapter and the ViewHolder as well.
After them, we gonna define a DiffUtil as well, which calculates the minimum number of changes between the old and the new list that’s been passed to the ReceyclerView.
So, create a new file in the bmis package, and name it as “BmisListAdapter”.
We are going to start the implementation with the ViewHolder. So, create a class indside of the BmisListAdapter‘s class with the name of “BmiViewHolder”.
It is going to have the ItemBmiBinding::class as a private constructor, and it has to be extended by RecyclerView.ViewHolder.
Header of the ViewHolder
Now, inside of the BmiViewHolder::class, we will bind the variables, what we have created in its layout.
Bind the variables
Next, we gonna inflate the layout inside of the companion object. It means, we can reach this method without having to instantiate the ViewHolder.
Inflate the layout
Calculating the differences
In this step we will define a callback, which will help us to compare 2 lists and it will calculate the differences between the lists, and the minimum number of changes between the old and the new list.
So, copy and paste the class into the BmisListAdapter.kt file, and be careful to do it outside of the BmisListAdapter::class.
Finishing the adapter
We are almost finished the adapter, only few things left.
The first thing is that we have to pass the BmisViewModel as constructure of the BmisListAdapter. Then we have to extend the adapter also.
Below you can see the header of the class.
Now, because we have extended our adapter, we have to implement some methods.
In the above methods we are just inflating the layout and passing the items for the ViewHolder.
That’s all, the adapter is finished. 😊
Step 4 - Bind the items
Our adapter is already finished, but still we haven’t uploaded any items to it. To solve this task, we gonna use Data Binding Adapter and we gonna create again a custom attribute for the RecyclerView.
So, open the DataBindingAdapter.kt file from the utils folder and paste the method at the end.
setItems Data Binding Adapter
Note that the name of the attribute is defined after the annotation.
Then see how we have defined the header of the function, because the first attribute has to be always the type of the view, where we can use the attribute.
Next, open the bmis_fragment.xml file from the res->layout folders and paste the below variable to the tags.
Now, we are able to pass the list of the items for the before created items attribute. The list is available in the BmisViewModel::class.
So, add the below line to the RecyclerView.
Step 5 - Setup the ListAdapter
In this step we will setup some things in the BmisFragment::class.
The first thing is thet we have to provide the BmisViewModel for the viewmodel variable inside of the layout file. So, add the below line to the onCreateView() method, directly before its return line.
binding.viewmodel = viewModel
Then this call to the onActivityCreated() method.
It is still red, so paste into the class its method.
Remove the observer
Previously we have created an obersver for the items’ list. Because of the Data Binding Adapter we don’t need it anymore. So, still in the BmisFragment::class go to the onActivityCreated() method and remove the item LiveData observer (it contains a Log).
Add the lifecycleowner
To have a working LiveData observer inside of the layout file, we have to provide the lifecycleowner of the view.
So, still in the onActivityCreated() method add the below line.
binding.lifecycleOwner = viewLifecycleOwner
Step 6 - Delete BMI
After… hopefully … a successful run, we are going to implement the delete feature. It means, when we press for a longer time an item inside of the RecyclerView, then a Bottom Sheet Dialog will popup where we will get a question to be sure we would like to delete the BMI and the action button for the delete.
So, open the BmisViewModel::class from the bmis package and add to it the below LiveData and 2 functions.
The deleteBmiDialog LiveData will notify the BmisFragment that we have longpressed the item and it will open the Bottom Sheet Dialog.
The 2 functions will be called from the layout of the item. So, open the item_bmi.xml file from the res->layout folder and add the below attribute to the ConstraintLayout.
Now you should have an error, because we haven’t defined the bmi variable inside of the layout file yet.
So, copy and paste the below bmi variable into the <data>/<data> tags, where you have already the viewmodel variable.
Next we have to add this bmi variable to the BmiViewHolder also. So open the BmisListAdapter::class and add the below line to the bind() method, what you can find in the BmiViewHolder.
binding.bmi = bmi
For the Bottom Sheet Dialog we need a layout also, which will be very simple, because it will contain only a TextView and 2 Buttons.
So, click with the right mouse button on the res->layout folder, select “New”, then the “Layout Resource file” option. In the popup window name it as “dialog_bottomsheet_deleteitem”.
Thenafter comes the xml code for the layout, what you can find below.
Layout of the bottom sheet
The next step is to setup the Bottom Sheet Dialog inside of the BmisFragment::class, so open it from the bmis package.
Then, add the below method call to the onActivityCreated() function.
Still this line will be in red, so paste after the onActivityCreated() function the below method.
I hope the description was understandable and clear. But, if you have still questions, then leave me comments below! 😉
Have a nice a day! 🙂
[Total: 0 Average: 0]