This example adds a list of places with image and name by using an ArrayList
of custom Place
objects as dataset.
The layout of the activity / fragment or where the RecyclerView is used only has to contain the RecyclerView. There is no ScrollView or a specific layout needed.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="<http://schemas.android.com/apk/res/android>"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
You could use any class or primitive data type as a model, like int
, String
, float[]
or CustomObject
. The RecyclerView will refer to a List
of this objects / primitives.
When a list item refers to different data types like text, numbers, images (as in this example with places), it is often a good idea to use a custom object.
public class Place {
// these fields will be shown in a list item
private Bitmap image;
private String name;
// typical constructor
public Place(Bitmap image, String name) {
this.image = image;
this.name = name;
}
// getters
public Bitmap getImage() {
return image;
}
public String getName() {
return name;
}
}
You have to specify a xml layout file that will be used for each list item. In this example, an ImageView
is used for the image and a TextView
for the name. The LinearLayout
positions the ImageView
at the left and the TextView
right to the image.
<?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:gravity="center_vertical"
android:orientation="horizontal"
android:padding="8dp">
<ImageView
android:id="@+id/image"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Next, you have to inherit the RecyclerView.Adapter
and the RecyclerView.ViewHolder
. A usual class structure would be:
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
// ...
public class ViewHolder extends RecyclerView.ViewHolder {
// ...
}
}
First, we implement the ViewHolder
. It only inherits the default constructor and saves the needed views into some fields:
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private TextView nameView;
public ViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.image);
nameView = (TextView) itemView.findViewById(R.id.name);
}
}
The adapter’s constructor sets the used dataset:
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
private List<Place> mPlaces;
public PlaceListAdapter(List<Place> contacts) {
mPlaces = contacts;
}
// ...
}
To use our custom list item layout, we override the method onCreateViewHolder(...)
. In this example, the layout file is called place_list_item.xml
.
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
// ...
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.place_list_item,
parent,
false
);
return new ViewHolder(view);
}
// ...
}