Understanding RecyclerView & Adapters in Android - Textnotes

Understanding RecyclerView & Adapters in Android


Learn how to use RecyclerView in Android to display large sets of data efficiently. Understand the ViewHolder pattern, Adapter usage, and how to improve performance.

RecyclerView is an advanced and flexible version of ListView in Android. It is used to display large lists of items in a more efficient way by reusing view elements that are no longer visible, thus improving performance. It is often paired with an Adapter to bind data to the view and a ViewHolder to optimize performance by caching views.

i) What is RecyclerView?

RecyclerView is a more flexible and efficient version of ListView. Unlike ListView, which creates a new view for each item, RecyclerView recycles and reuses views that are no longer visible to the user, which improves performance significantly when dealing with large datasets. It is ideal for displaying long lists of items, grids, and even complex layouts.

RecyclerView can be customized in a variety of ways, including its layout manager, animations, and item decorations. It has three key components:

  1. RecyclerView: The widget used to display the list.
  2. Adapter: Binds the data to the RecyclerView.
  3. ViewHolder: Holds references to the views that represent an item in the list.

ii) RecyclerView Adapter

An Adapter in RecyclerView is used to bind data to the views inside each item. It acts as a bridge between the data source and the views in the RecyclerView. The adapter must override several methods, such as onCreateViewHolder(), onBindViewHolder(), and getItemCount(), to create, bind, and count the data.

Steps to Implement RecyclerView Adapter

  1. Create a ViewHolder Class
  2. A ViewHolder is used to cache the views for an individual item in the list. It is an optimization technique to prevent the need for repeatedly finding the same views within the list.

public class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;

public MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
}
}
  1. Create the Adapter Class
  2. The adapter is responsible for inflating the item layout and binding data to the views in each ViewHolder.

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<String> data;

public MyAdapter(List<String> data) {
this.data = data;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_item_layout, parent, false);
return new MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
String item = data.get(position);
holder.textView.setText(item);
}

@Override
public int getItemCount() {
return data.size();
}
}
  1. Set Up RecyclerView
  2. The RecyclerView widget needs to be initialized and its layout manager and adapter set. The layout manager determines how the items in the RecyclerView are displayed (e.g., in a linear list, grid, etc.).

RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
MyAdapter adapter = new MyAdapter(myDataList);
recyclerView.setAdapter(adapter);

iii) ViewHolder Pattern for Optimizing RecyclerView Performance

The ViewHolder pattern is used to optimize the performance of RecyclerView. Without it, every time an item becomes visible, the RecyclerView must call findViewById() on every view inside the item layout. This can lead to unnecessary overhead and reduce performance.

The ViewHolder caches references to all the views in an item layout, and this prevents findViewById() from being called multiple times, improving performance significantly.

How ViewHolder Works

  1. ViewHolder is a class that holds references to views for each item.
  2. onCreateViewHolder() is called when a new ViewHolder needs to be created.
  3. onBindViewHolder() is called to bind data to the views inside the ViewHolder.
  4. The RecyclerView reuses views through the Recycler class, so when a view is no longer visible, it is recycled and reused for the next item.

Here's an example of how the ViewHolder pattern works:


public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

private List<String> data;

public MyAdapter(List<String> data) {
this.data = data;
}

// ViewHolder pattern implemented here
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_item_layout, parent, false);
return new MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
String item = data.get(position);
holder.textView.setText(item);
}

@Override
public int getItemCount() {
return data.size();
}

public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;

public MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
}
}
}

iv) RecyclerView Layout Managers

RecyclerView requires a LayoutManager to arrange the items. There are different types of layout managers available in Android:

  1. LinearLayoutManager: Displays items in a vertical or horizontal list.
  2. GridLayoutManager: Displays items in a grid with rows and columns.
  3. StaggeredGridLayoutManager: Displays items in a staggered grid where items can have different heights.

Example: Using LinearLayoutManager


RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

v) RecyclerView Item Decorations

You can add Item Decorations to your RecyclerView to customize the appearance of items, such as adding dividers between items.

For example, to add a divider between items:


RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));

vi) Example Code: RecyclerView with Adapter and ViewHolder


public class MainActivity extends AppCompatActivity {

RecyclerView recyclerView;
MyAdapter adapter;
List<String> myDataList;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

recyclerView = findViewById(R.id.recyclerView);

// Sample data
myDataList = new ArrayList<>();
for (int i = 0; i < 50; i++) {
myDataList.add("Item " + i);
}

// Set up RecyclerView with LayoutManager and Adapter
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyAdapter(myDataList);
recyclerView.setAdapter(adapter);
}
}

Conclusion

In this tutorial, you’ve learned how to use RecyclerView to efficiently display large datasets in Android. You also explored how the ViewHolder pattern works and how to use Adapters to bind data to views. By understanding these concepts, you can implement better-performing Android apps that handle large amounts of data smoothly.