The correct way of implementing getItemId() in RecyclerView.Adapter

14,661

Solution 1

  1. Create a base interface that has a method that returns a type long eg.

    interface BaseInterface{
        long getId(); 
    }
    
  2. Change

    abstract class BaseAdapter<T> extends RecyclerView.Adapter 
    

    to

    abstract class BaseAdapter<T extends BaseInterface> extends RecyclerView.Adapter {
    

    Note: The signature changed to T extends BaseInterface

  3. Replace

    @Override
    public long getItemId(int position) {
        return position;
    }
    

    with

    @Override
    public long getItemId(int position) {
        return itemsList.get(position).getId();
    }
    

Solution 2

In the List you could only return the Id of the Item available at specific row as mentioned by Google documents:

getItemId

Get the row id associated with the specified position in the list.

But that's not the case with RecyclerView, in RecyclerView you have to ensure that you either return a unique Id for each Item or In case of no Stable Id you should return RecyclerView.NO_ID (-1). Please Refrain from returning values that are not stable. (An Stable value would be a unique value that does not change even if position of dataset changes)

Solution 3

you should implement this methode: as you see you must tell the Adapter that you implemented that by setHasStableIds(true);

class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
MyAdapter() {
    setHasStableIds(true); // **very importent**
}

@Override
public long getItemId(int position) {
    // requires unique value, it means need to keep the same value
    // even if the item position has been changed.
    return mItems.get(position).getId();
}

}

Share:
14,661
Sky
Author by

Sky

Updated on June 03, 2022

Comments

  • Sky
    Sky about 2 years

    I have generic class

    public abstract class BaseAdapter<T> extends RecyclerView.Adapter {
      private List<T> itemsList = new ArrayList<>();
      //other override methods
    
      @Override
        public long getItemId(int position) {
            return position;
        }
    }
    

    What is the correct way to implementing getItemId()? I think that return position like in many example is not correct.

  • Sky
    Sky over 7 years
    itemsList has type <T>. And has only default lists methods
  • Sky
    Sky over 7 years
    and itemsList.get(position). has objects methods
  • David
    David about 6 years
    The Google I/O app itself returns position as fallback, I wonder if this is OK github.com/google/iosched/blob/…
  • Hasan El-Hefnawy
    Hasan El-Hefnawy about 5 years
    Exactly, the behavior of getItemId in RecyclerView.Adapter differs from getItemId in ArrayAdapter.
  • Big McLargeHuge
    Big McLargeHuge about 5 years
    What about hashCode() instead of getId()?
  • Bubunyo Nyavor
    Bubunyo Nyavor about 5 years
    hashCode() implementation cannot be enforced. If an interface forgets to implement it, it will not throw an error.
  • ansh sachdeva
    ansh sachdeva over 3 years
    can you explain why this code gives a static value? to me it looks like mItems.get(position) returns an instance of your model class , which has a a function returning some integer id. why would your model return the same id again and again? If you are using dbs or network, then usually the id is unique and getId() returns a unique value everytime
  • Amir Hossein
    Amir Hossein over 3 years
    You're right. By "static" I mean unique value for each item. Not a same value.
  • ansh sachdeva
    ansh sachdeva over 3 years
    Then please change the word static to unique , as this gives a totally different meaning, and newbies like me spend 10 minutes on this answer to get even more confused :P