RecyclerView is an advanced version of GridView and ListView, introduced in Marshmallow. It extends the ViewGroup class and implements the ScrollingView interface. RecyclerView helps us when displaying an excessive amount of data. To use RecyclerView we need to give the data, the state, and information about how every element should look, then the library will do the work of creating elements dynamically so that we can use them when needed.
The above photo shows different layouts that we can choose in RecyclerView, such as grid, linear layout (horizontal or vertical), etc. Columns and rows can be arranged according to our convenience.
There are some important classes of RecyclerView of which we should be aware.
This class is used for handling item animations.
This class uses an object to set up manual divider decorations.
In a list, every individual element will be defined by a view holder object. RecyclerView binds the view holder to its data after it is created since when it gets created it doesn’t have data associated with it. We can define the view holder by extending RecyclerView.ViewHolder.
LayoutManager sets every element in your list. RecyclerView library provides the LayoutManager, or you can use another layout manager.
RecyclerView comes with an adapter that is responsible to request views and responsible for binding the views to their data, by calling a method in it.
We need to override three key methods when defining adapter:
onCreateViewHolder(): When RecyclerView needs to make a new ViewHolder it calls this method. This method is helpful in making, initializing, and associating ViewHolder with a view. The ViewHolder is not yet bound to specific data, which means it does not fill in the view’s content.
onBindViewHolder(): After the creation of ViewHolder we need to associate it with data. At this stage the RecyclerView calls onBindViewHolder() method. This method is the one that fetches required data and uses it to fill in ViewHolder’s layout. An example includes the condition when we need to get an appropriate name from a list of names and then use it to fill in the view holder’s TextView widget.
geItemCount(): To get the size of data we have a getItemCount() method. This method is used by RecyclerView to find any further items that are left to display. An example is the total number of entries in the phone book.
Gradle Dependency:-
build.gradle(app module)
1 2 3 4 5
dependencies { ... implementation "androidx.recyclerview:recyclerview:1.2.1" ... }
CardView is a new widget in Android used for any sort of data with a rounded corner background and shadow. Sometimes we require a way to display data in containers that are similarly styled (we can use such containers to hold information about items in the list). We have a CardView API to show information inside the cards which have consistency across all platforms. The system draws shadows below cards since these cards have default elevation above their containing view group. Cards are used when we need to group views while providing a consistent style for the container.
The above image shows an example of CardView in which we have different cards named after the countries. We can have different color schemes for different cards, we have the flexibility to set borders and other styles based on our needs.
There are some useful attributes of CardView as follows.
Used in the layout to set the corner radius.
This method is used to set the background color of a card.
This method is used to set the corner radius in your code. It is another method to set radius which can be used in a java file.
Gradle Dependency:-
build.gradle(app module)
1 2 3 4 5
dependencies { ... implementation“ androidx.cardview: cardview: 1.0 .0” ... }
In this example, we will make an application by using both RecyclerView and CardView. Each file code is given below.
activity_main.xml
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"?> <!-- using linear layout you can use use a different layout if you want --> <LinearLayout 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:orientation="vertical" tools:context=".MainActivity"> <!-- Button to add new android version so that we can see it is working fine with new items --> <Button android:id="@+id/btadd" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/add" /> <!-- RecyclerView with id ListR to display all content in it --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/ListR" android:layout_width="match_parent" android:layout_height="wrap_content"> </androidx.recyclerview.widget.RecyclerView> </LinearLayout>
list_item .xml
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
<?xml version="1.0" encoding="utf-8"?> <!-- I am using Linear layout in this case with vertical orientation --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- For implementing the cardView --> <androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" card_view:cardBackgroundColor="#f6f6f6" card_view:cardCornerRadius="3dp" card_view:cardElevation="5dp" card_view:cardUseCompatPadding="false" android:layout_margin="7dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- A nested Linear Layout inside the cardView with orientation horizonatal --> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <!-- ImageView to show icon we picked --> <ImageView android:id="@+id/ivicon" android:layout_width="50dp" android:layout_height="50dp" app:srcCompat="@drawable/android_donut" /> <!-- another nested Linear layout with vertical orientation so that we can arrange both textView --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <!--TextView for displaying name of android--> <TextView android:id="@+id/tvnam" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView" android:textSize="14sp" android:textStyle="bold" /> <!--TextView for displaying the version of android--> <TextView android:id="@+id/tvversion" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView" android:textSize="14sp" android:textStyle="bold" /> </LinearLayout> <!-- close the innermost linear layout--> </LinearLayout> <!-- Close the inner linear layout--> </androidx.cardview.widget.CardView> <!-- Close cardView --> </LinearLayout>
MainActivity.java
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
package com.explme.recyclerandcardview;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements androidVersionAdapter.ItemClicked {
RecyclerView recyclerView;
RecyclerView.Adapter myAdapter;
RecyclerView.LayoutManager layoutManager;
ArrayList < androidVersion > people;
Button btadd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.ListR);
btadd = findViewById(R.id.btadd);
btadd.setOnClickListener(view - > {
people.add(new androidVersion("Android Q", "10.0.0_r64", "Q"));
myAdapter.notifyDataSetChanged();
});
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
people = new ArrayList < androidVersion > ();
people.add(new androidVersion("Cupcake", "1.5", "Cupcake"));
people.add(new androidVersion("Donut", "1.6", "donut"));
people.add(new androidVersion("Eclair", "2.0-2.1", "eclair"));
people.add(new androidVersion("Gingerbread", "2.2-2.3", "gingerbread"));
people.add(new androidVersion("Honeycomb", "2.3-3.7", "honeycomb"));
people.add(new androidVersion("Ice Cream Sandwich", "3.0-3.2.6", "icecreamsandwich"));
people.add(new androidVersion("JellyBean", "4.0-4.3.1", "jellybean"));
people.add(new androidVersion("Kitkat", "4.4-4.4.4", "kitkat"));
people.add(new androidVersion("Lollipop", "5.0-5.1.1", "lollipop"));
people.add(new androidVersion("Marshmallow", "6.0-6.0.1", "marshmallow"));
myAdapter = new androidVersionAdapter(this, people);
recyclerView.setAdapter(myAdapter);
}
@Override
public void onItemClicked(int index) {
Toast.makeText(this, "Version :" + people.get(index)
.getVersion(), Toast.LENGTH_LONG)
.show();
}
}
androidVersion.java
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
package com.explme.recyclerandcardview;
public class androidVersion {
String name;
String version;
String prefer;
public androidVersion(String name, String version, String prefer) {
this.name = name;
this.version = version;
this.prefer = prefer;
}
// get name of android through this
public String getName() {
return name;
}
// set name of android through this
public void setName(String name) {
this.name = name;
}
// get version of android through this
public String getVersion() {
return version;
}
// set version of android through this
public void setVersion(String version) {
this.version = version;
}
// get prefer name of android through this
public String getPrefer() {
return prefer;
}
// set prefer name of android through this
public void setPrefer(String prefer) {
this.prefer = prefer;
}
}
androidVersionAdapter.java
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
package com.explme.recyclerandcardview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class androidVersionAdapter extends RecyclerView.Adapter < androidVersionAdapter.Viewholder > {
// array list to store all items
private ArrayList < androidVersion > androidList;
// object of type ItemClicked to get our mainActivity using context passed in androidVersionAdapter
ItemClicked activity;
//set an interface
public interface ItemClicked {
void onItemClicked(int index);
}
//in this we will set our context i.e. mainActivity to activity object and arrayList
public androidVersionAdapter(Context context, ArrayList < androidVersion > List) {
androidList = List; //arrayList
activity = (ItemClicked) context; //mainActivity reference
}
public class Viewholder extends RecyclerView.ViewHolder {
ImageView ivicon; //for imageView icon
TextView tvnam, tvversion; //for textView name and version of android
//declate viewholder
public Viewholder(@NonNull View itemView) {
super(itemView);
tvnam = itemView.findViewById(R.id.tvnam); //find and set android name TextView
tvversion = itemView.findViewById(R.id.tvversion); //find and set android version textView
ivicon = itemView.findViewById(R.id.ivicon); //find and set android icon ImageView
}
}
//onCreateViewHolder method to return and set Viewholder
@NonNull
@Override
public androidVersionAdapter.Viewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new Viewholder(v); //return viewholder
}
//onBindViewHolder method to bind different resourses with our holder
@Override
public void onBindViewHolder(@NonNull androidVersionAdapter.Viewholder holder, int position) {
holder.itemView.setTag(androidList.get(position)); //get the position in the arrayList
holder.tvnam.setText(androidList.get(position)
.getName()); //set text for name of android
holder.tvversion.setText(androidList.get(position)
.getVersion()); //set text for version
if (androidList.get(position)
.getPrefer()
.equals("cupcake")) {
holder.ivicon.setImageResource(R.drawable.android_cupcake); //get icon
} else {
holder.ivicon.setImageResource(R.drawable.android_donut); //get icon
}
}
//getItemCount method for returning the size of arrayList
@Override
public int getItemCount() {
return androidList.size();
}
}
RecyclerView and CardView give us a lot of flexibility when designing. They provide us with many different inbuild classes and attributes to make designing easier. We can do the same work without RecyclerView and CardView but styles and design will be less attractive and it will become much more difficult to code.