130

I'm still trying to get my head around recyclerview. I have an arraylist, that I use to initialize a recycler view with.

How can I add new items to the recycler view post setting an adapter and layoutmanager?

private void initData() {
        mItems = new ArrayList<String>();
        for (int i = 0; i < ITEMS_COUNT; i++) {
            mItems.add("Item " + (i + 1));
        }
    }

    private void initRecyclerView() {
        mRecentRecyclerView = (RecyclerView) findViewById(R.id.recentrecyclerView);
        mRecentRecyclerView.setHasFixedSize(true);
        mRecentLayoutManager = new LinearLayoutManager(this);
        mRecentRecyclerView.setLayoutManager(mRecentLayoutManager);



        mAdapter = new RecyclerView.Adapter<CustomViewHolder>() {
            @Override
            public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
                View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.notice_snippet
                        , viewGroup, false);
                return new CustomViewHolder(view);
            }

            @Override
            public void onBindViewHolder(CustomViewHolder viewHolder, int i) {
                viewHolder.noticeSubject.setText(mItems.get(i));
            }

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

        };
        mRecentRecyclerView.setAdapter(mAdapter);

    private class CustomViewHolder extends RecyclerView.ViewHolder {

        private TextView noticeSubject;

        public CustomViewHolder(View itemView) {
            super(itemView);

            noticeSubject = (TextView) itemView.findViewById(R.id.notice_subject);
        }
    }

So basically after I initdata() and initRecyclerView(), how do i add a new item to the RecyclerView??

Cœur
  • 37,241
  • 25
  • 195
  • 267
Shubham Kanodia
  • 6,036
  • 3
  • 32
  • 46
  • You can see [this example in Github](https://github.com/CabezasGonzalezJavier/FullRecycleView/tree/master/app/src/main/java/com/thedeveloperworldisyours/fullrecycleview/vertical) Happy code!!! – Cabezas Feb 01 '17 at 12:25

3 Answers3

306

First add your item to mItems and then use:

mAdapter.notifyItemInserted(mItems.size() - 1);

this method is better than using:

mAdapter.notifyDataSetChanged();

in performance.

Mostafa
  • 3,175
  • 1
  • 15
  • 9
  • 15
    Good answer. It also means that it won't break animations – Ben Pearson Jun 19 '15 at 14:12
  • 7
    This should be accepted as right answer, the other one breaks animations and is less efficient than this one. – Massimo Jul 28 '15 at 14:25
  • 34
    I am the one who answered the accepted answer and I think this should be the accepted one :D – Abdelrahman Elkady Aug 18 '15 at 11:18
  • what if i have to add 10 more items in one go? – Vinay W Dec 18 '15 at 11:38
  • Using the code just for the last item seems to work. Don't need to do it for all the newly inserted items . – Vinay W Dec 21 '15 at 10:52
  • 1
    @Mostafa What does the "-1" do at the end of your "notifyItemInserted" do? Does it say that if the numbers of items starts with zero, then the item will be inserted at the end of the list each time? – AJW Jan 20 '16 at 04:52
  • 2
    @AJW yes. index of last element of mItems is mItems.size()-1. – Mostafa Jan 20 '16 at 08:38
  • 2
    Thanks! I have images that should be loaded from internet in onBindViewHolder. Every time I receive data, I need to append to the list and called notifyDataSetChanged(). But this made a image flickering effect. Above was the right solution I was searching for. You can also use mAdapter.notifyItemRangeInserted(mItems.size() - 1, new_array_of_items_to_be_added.size()); – GOBINATH.M Aug 18 '16 at 08:42
  • The first mentioned approach will not work until you just add one item to the list. The reason can be found in the RecyclerView, where the list of items is traversed in a way which misbehaves in my opinion. My quick solution is: ```int position = getItemCount() - 1;``` if (position != 0) { notifyItemInserted(position); } else { notifyDataSetChanged(); } – drindt Dec 12 '17 at 09:44
  • How about insert at first of recycler view? – quangkid Mar 20 '21 at 03:18
45

simply add to your data structure ( mItems ) , and then notify your adapter about dataset change

private void addItem(String item) {
  mItems.add(item);
  mAdapter.notifyDataSetChanged();
}

addItem("New Item");
Abdelrahman Elkady
  • 2,518
  • 2
  • 21
  • 30
  • 2
    What if it's not a string I wanna add, but a ViewGroup? – IgorGanapolsky May 14 '15 at 19:59
  • 1
    @IgorGanapolsky I also have the same doubt. Did you find any solution for that? – Sash_KP Jun 23 '15 at 06:24
  • same doubt here too! any help? – Srujan Barai Jul 20 '15 at 17:03
  • I want to call `addItem()` from another adapter class but `addItem()` is a non-static method and hence cannot take non-static calls. Which object should I use to call this method? – Srujan Barai Jul 20 '15 at 19:16
  • 5
    @IgorGanapolsky The item type would be specified by your Adapter, so it could be really any object. But keep in mind the item your adding is just supposed to be the data. The RecyclerView has built in functions for inflating and binding a view, which is what will happen when you notifyDataSetChanged(). You can debug the onBindViewHolder to see the view being edited. – Chris Jul 24 '15 at 20:20
  • 1
    @IgorGanapolsky Your `ArrayList` would have to use the type of object you wanna add, e.g. `ArrayList` instead of `ArrayList`. Then you can just change the argument type from `String` to `ViewGroup`. (Sorry for necro). – Eric Reed Jun 25 '19 at 02:00
18

if you are adding multiple items to the list use this:

mAdapter.notifyItemRangeInserted(startPosition, itemcount);

This notify any registered observers that the currently reflected itemCount items starting at positionStart have been newly inserted. The item previously located at positionStart and beyond can now be found starting at position positinStart+itemCount

existing item in the dataset still considered up to date.

Nitin Anand
  • 795
  • 6
  • 9