How to update RecyclerView Adapter Data
This is a general answer. The various ways to update the adapter data are explained. The process includes two main steps every time:
- Update the data set
- Notify the adapter of the change
Insert single item
Add "Pig" at index 2
.
String item = "Pig";int insertIndex = 2;data.add(insertIndex, item);adapter.notifyItemInserted(insertIndex);
Insert multiple items
Insert three more animals at index 2
.
ArrayList<String> items = new ArrayList<>();items.add("Pig");items.add("Chicken");items.add("Dog");int insertIndex = 2;data.addAll(insertIndex, items);adapter.notifyItemRangeInserted(insertIndex, items.size());
Remove a single item
Remove "Pig" from the list.
int removeIndex = 2;data.remove(removeIndex);adapter.notifyItemRemoved(removeIndex);
Remove multiple items
Remove "Camel" and "Sheep" from the list.
int startIndex = 2; // inclusiveint endIndex = 4; // exclusiveint count = endIndex - startIndex; // 2 items will be removeddata.subList(startIndex, endIndex).clear();adapter.notifyItemRangeRemoved(startIndex, count);
Remove all items
Clear the whole list.
data.clear();adapter.notifyDataSetChanged();
Replace old list with the new list
Clear the old list then add a new one.
// clear old listdata.clear();// add new listArrayList<String> newList = new ArrayList<>();newList.add("Lion");newList.add("Wolf");newList.add("Bear");data.addAll(newList);// notify adapteradapter.notifyDataSetChanged();
The adapter
has a reference to data
, so it is important that I didn't set data
to a new object. Instead, I cleared the old items from data
and then added the new ones.
Update single item
Change the "Sheep" item so that it says "I like sheep."
String newValue = "I like sheep.";int updateIndex = 3;data.set(updateIndex, newValue);adapter.notifyItemChanged(updateIndex);
Move a single item
Move "Sheep" from position 3
to position 1
.
int fromPosition = 3;int toPosition = 1;// update data arrayString item = data.get(fromPosition);data.remove(fromPosition);data.add(toPosition, item);// notify adapteradapter.notifyItemMoved(fromPosition, toPosition);
Code
Here is the project code for your reference. The RecyclerView Adapter code can be found at this answer.
MainActivity.java
public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener { List<String> data; MyRecyclerViewAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // data to populate the RecyclerView with data = new ArrayList<>(); data.add("Horse"); data.add("Cow"); data.add("Camel"); data.add("Sheep"); data.add("Goat"); // set up the RecyclerView RecyclerView recyclerView = findViewById(R.id.rvAnimals); LinearLayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), layoutManager.getOrientation()); recyclerView.addItemDecoration(dividerItemDecoration); adapter = new MyRecyclerViewAdapter(this, data); adapter.setClickListener(this); recyclerView.setAdapter(adapter); } @Override public void onItemClick(View view, int position) { Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show(); } public void onButtonClick(View view) { insertSingleItem(); } private void insertSingleItem() { String item = "Pig"; int insertIndex = 2; data.add(insertIndex, item); adapter.notifyItemInserted(insertIndex); } private void insertMultipleItems() { ArrayList<String> items = new ArrayList<>(); items.add("Pig"); items.add("Chicken"); items.add("Dog"); int insertIndex = 2; data.addAll(insertIndex, items); adapter.notifyItemRangeInserted(insertIndex, items.size()); } private void removeSingleItem() { int removeIndex = 2; data.remove(removeIndex); adapter.notifyItemRemoved(removeIndex); } private void removeMultipleItems() { int startIndex = 2; // inclusive int endIndex = 4; // exclusive int count = endIndex - startIndex; // 2 items will be removed data.subList(startIndex, endIndex).clear(); adapter.notifyItemRangeRemoved(startIndex, count); } private void removeAllItems() { data.clear(); adapter.notifyDataSetChanged(); } private void replaceOldListWithNewList() { // clear old list data.clear(); // add new list ArrayList<String> newList = new ArrayList<>(); newList.add("Lion"); newList.add("Wolf"); newList.add("Bear"); data.addAll(newList); // notify adapter adapter.notifyDataSetChanged(); } private void updateSingleItem() { String newValue = "I like sheep."; int updateIndex = 3; data.set(updateIndex, newValue); adapter.notifyItemChanged(updateIndex); } private void moveSingleItem() { int fromPosition = 3; int toPosition = 1; // update data array String item = data.get(fromPosition); data.remove(fromPosition); data.add(toPosition, item); // notify adapter adapter.notifyItemMoved(fromPosition, toPosition); }}
Notes
- If you use
notifyDataSetChanged()
, then no animation will be performed. This can also be an expensive operation, so it is not recommended to usenotifyDataSetChanged()
if you are only updating a single item or a range of items. - Check out DiffUtil if you are making large or complex changes to a list.
Further study
I'm working with RecyclerView and both the remove and the update work well.
Remove:
There are four steps to remove an item from a RecyclerView
list.remove(position); recycler.removeViewAt(position); mAdapter.notifyItemRemoved(position); mAdapter.notifyItemRangeChanged(position, list.size());
These lines of code work for me.
Update the data:
The only things I had to do was:
mAdapter.notifyDataSetChanged();
You had to do all of this in the Actvity/Fragment code, not in the RecyclerView Adapter code.
This is what worked for me:
recyclerView.setAdapter(new RecyclerViewAdapter(newList));recyclerView.invalidate();
After creating a new adapter that contains the updated list (in my case it was a database converted into an ArrayList) and setting that as adapter, I tried recyclerView.invalidate()
and it worked.