Recyclerview on Scrolling values changing from adapter
Just have to override two methods in your Adapter and it will solve your issue.
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
Just Override these methods in your adapter class:
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
This link will help you to get the understanding of the concept behind.
How to fix Recyclerview shuffling issue
adding this in the adapter solved the problem
@Override
public int getItemViewType(int position)
{
return position;
}
Note: I strongly recommend not to use any solution that suggests using unique view types for all list items, by assigning the position number to the view type by overriding getItemViewType()
. Doing so will make the RecyclerView think that all the items in the list have a different type of layout and so each item will be created separately from scratch. This will result in increasing the app's main memory usage and also the load time of the activity or fragment that contains the RecyclerView.
Simple Optimal Solution with Explanation
The items are getting shuffled because the item's ViewHolder is not updated properly inside onBindViewHolder()
. To know why this behavior occurs, first lets understand how exactly the RecyclerView recycles the list items.
By default, the RecyclerView will only create the number of items that can be shown on the device's screen. This means, even if there are hundreds or thousands of list items in the list, if the device can only show 10 items on its screen at a time, then approximately only 10 items will be created and stored in the main memory(RAM). When the screen is scrolled these same 10 items will be updated with the new content instead of creating the item and its layout again. In the below image you can see the 1st item getting recycled by only updating the text from ABC to XYZ. The background color red of the previous item remains the same.
Image Source: Google Codelabs
More specifically, while scrolling, instead of garbage collecting the scrolled off item's ViewHolder and creating a new one, the RecyclerView will use the same scrolled off item's ViewHolder and updates it with the upcoming new list item's properties. (A ViewHolder is something that holds the views of a particular list item and the properties that describe it)
This update handling is done by overriding the onBindViewHolder()
method which gets called whenever a new item needs to be shown on the screen. The reason why the values on your list shuffles have something to do with how the ViewHolder is being updated inside this method. As I said before, since the list items get recycled while scrolling the list, the ViewHolder that you obtain as a parameter for onBindViewHolder()
will already be assigned with some other list item's properties. So, you need to make sure that all the properties of this ViewHolder are either replaced according to your new list item's property or reset back to the default one. To do so, check whether you're using any conditions inside this method and make sure that you add a default condition to it that will reset that particular view's property to the default one.
Example:-
if (<CONDITION>) {
holder.textView.setText("New Text")
} else {
// RESET. Missing to reset the text would lead to the issue.
holder.textView.setText("Default Text")
}
In case if you're still not having a clear understanding of RecyclerView's working then I'd recommend you to go through the RecyclerView Fundamentals codelab by Google. In this codelab they've exclusively addressed this recycling issue in Step 6 of its first task.