In short, the less you work with the onBindViewHolder() method, the better the performance of scrolling a list.
The most efficient implementation simply takes data from the transferred model and simply sets it into the view holder.
Since all this work in the onBindViewHolder() method is performed in the user interface thread, unloading any additional work either before binding or shipping to the anthoer stream is beneficial for displaying list performance.
For example , let's say that you have a list containing many tasks, as shown below:
class Task { Date dateDue; String title; String description;
Each task has a name, description and date associated with it. As a requirement for your application, if today's date precedes the set date, the line should be green, and if it matches the set date, it should be red. In addition, the associated Task object requires special date formatting before setting it to the view.
There are two things in this onBindViewHolder() , since each row is displayed on the screen:
- You will need to conditionally check each date and compare it with today's date.
- You will need to apply the date format to get the date representation in the required specification:
eg.
class MyRecyclerView.Adapter extends RecyclerView.Adapter { static final TODAYS_DATE = new Date(); static final DATE_FORMAT = new SimpleDateFormat("MM dd, yyyy"); public onBindViewHolder(Task.ViewHolder tvh, int position) { Task task = getItem(position); if (TODAYS_DATE.compareTo(task.dateDue) > 0) { tvh.backgroundView.setColor(Color.GREEN); } else { tvh.backgroundView.setColor(Color.RED); } String dueDateFormatted = DATE_FORMAT.format(task.getDateDue()); tvh.dateTextView.setDate(dueDateFormatted); } }
In the example above, for each row that is displayed, a date comparison is performed. While we were on it, we even took the liberty of making today's date permanent - creating an object is probably one of the most expensive things you can do in onBindViewHolder() , so any optimization is appreciated. In addition, the date that is transmitted in the Task object was not in the correct format, so it is also formatted, which is also "on the fly."
Although this example is trivial, it can quickly activate scrolling list scrolling before crawling. The best way to do this is to pass in an intermediate object, such as a presentation model, that represents the state of the view instead of the actual business model.
Instead of passing Task as an adapter model, we create an intermediate model called TaskViewModel , which is created and installed on the adapter. Now, before installing any information sent to the adapter, all the work is done before the view visualization is applied. This is due to the longer initialization time before sending the data to your RecyclerView , but with a better compromise on the performance of the list view.
This presentation model can be:
public class TaskViewModel { int overdueColor; String dateDue; }
Now that you are tasked with attaching data to the view, we have the actual state of the view, which is presented in the view model, and our UI thread can continue to be free.
public onBindViewHolder(Task.ViewHolder tvh, int position) { TaskViewModel taskViewModel = getItem(position); tvh.backgroundView.setColor(taskViewModel.getOverdueColor()); tvh.dateTextView.setDate(taskViewModel.getDateDue()); }