How to update RecyclerView Adapter Data?

前端 未结 13 2330
误落风尘
误落风尘 2020-11-22 03:48

Trying to figure out what is the issue with updating RecyclerView\'s Adapter.

After I get a new List of products, I tried to:

  1. Update t

13条回答
  •  再見小時候
    2020-11-22 04:11

    This is a general answer for future visitors. The various ways to update the adapter data are explained. The process includes two main steps every time:

    1. Update the data set
    2. Notify the adapter of the change

    Insert single item

    Add "Pig" at index 2.

    Insert single item

    String item = "Pig";
    int insertIndex = 2;
    data.add(insertIndex, item);
    adapter.notifyItemInserted(insertIndex);
    

    Insert multiple items

    Insert three more animals at index 2.

    Insert multiple items

    ArrayList 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 single item

    Remove "Pig" from the list.

    Remove single item

    int removeIndex = 2;
    data.remove(removeIndex);
    adapter.notifyItemRemoved(removeIndex);
    

    Remove multiple items

    Remove "Camel" and "Sheep" from the list.

    Remove multiple items

    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);
    

    Remove all items

    Clear the whole list.

    Remove all items

    data.clear();
    adapter.notifyDataSetChanged();
    

    Replace old list with new list

    Clear the old list then add a new one.

    Replace old list with new list

    // clear old list
    data.clear();
    
    // add new list
    ArrayList newList = new ArrayList<>();
    newList.add("Lion");
    newList.add("Wolf");
    newList.add("Bear");
    data.addAll(newList);
    
    // notify adapter
    adapter.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."

    Update single item

    String newValue = "I like sheep.";
    int updateIndex = 3;
    data.set(updateIndex, newValue);
    adapter.notifyItemChanged(updateIndex);
    

    Move single item

    Move "Sheep" from position 3 to position 1.

    Move single item

    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);
    

    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 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 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 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 use notifyDataSetChanged() 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

    • CodePath: Using the RecyclerView
    • Smart way to update RecyclerView using DiffUtil

提交回复
热议问题