Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getAdapterPosition() is deprecated

I've updated my targetSdkVersion from 28 to 30 and I've noticed that getAdapterPosition() is deprecated (I'm not sure when this happened).

In the documentation, they say the following:

This method is deprecated.
This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition() or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition().

The documentation also says the following:

Note that if you are querying the position as RecyclerView sees, you should use getAbsoluteAdapterPosition() (e.g. you want to use it to save scroll state). If you are querying the position to access the RecyclerView.Adapter contents, you should use getBindingAdapterPosition().

How I understand it is:

  • getBindingAdapterPosition should be used when you want to get the adapter position (if it still exists in the adapter). If it no longer exists in the adapter, it will return -1(NO_POSITION).
  • getAbsoluteAdapterPosition should be used to get the position as the RecyclerView sees it. For example, if an item has been deleted, but not yet removed from theViewHolder.

In other words, if I have 4 items in my Adapter, I delete position 0 and query getAbsoluteAdapterPosition and getBindingAdapterPosition before the item has been removed from the ViewHolder, then getAbsoluteAdapterPosition will return 0(because view is still in the ViewHolder) and getBindingAdapterPosition return -1(Because it no longer exists in the adapter).


I have tested the difference by logging the following:

Log.e("difference", "getAdapterPosition = "+myHolder.getAdapterPosition()+" getBindingAdapterPosition = "+myHolder.getBindingAdapterPosition()+" getAbsoluteAdapterPosition = "+myHolder.getAbsoluteAdapterPosition());

They return exactly the same values. I could not see any difference.

I also see no difference before or after calling notifyItemChanged, notifyDataSetChanged or notifyItemRangeChanged. But when I delete position 0 and call notifyItemRemoved it returns -1 afterward (for all of them).

My questions

Do I understand this correctly, and when should we be using which? Also, when will there be a difference?

like image 451
ClassA Avatar asked Jul 24 '20 07:07

ClassA


People also ask

What is a ViewHolder in Android?

A ViewHolder describes an item view and metadata about its place within the RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive findViewById results.

How do I use concat adapter?

Merging Adapters with ConcatAdapterInside your Activity or Fragment class, you need to create the instances of all these adapters and populate data into them. In the normal case, you would have to add 3 separate RecyclerView s, but now you only need to add a single RecyclerView in your XML file.

Is the method viewholder getadapterposition deprecated?

With version 1.2.0 of androidx.recyclerview:recyclerview the method ViewHolder.getAdapterPosition is deprecated. ConcatAdapter: This new adapter allows you to easily concatenate multiple Adapters on the same RecyclerView. See the blog post for more information.

Is the method to get adapter position deprecated in Android?

This method is deprecated. This method is confusing when adapters nest other adapters. If you are calling this in the context of an Adapter, you probably want to call getBindingAdapterPosition () or if you want the position as RecyclerView sees it, you should call getAbsoluteAdapterPosition ().

What is the difference between getbindingadapterposition and getabsoluteadapterposition?

getBindingAdapterPosition returns the position relative to the Adapter which bound that item. getAbsoluteAdapterPosition returns the position relative to the whole RecyclerView.

Is Android recyclerview on itemclicklistener&getadapterposition () the right way?

Android RecyclerView on ItemClickListener & getAdapterPosition () (…and many other things) is not always the correct or a better way to get that thing done smoothly. Instead of creating a custom interface to get adapter position () inside your Activity/Fragment/View and end up creating multiple Anonymous Classes under the hood for each item.


1 Answers

The recyclerview:1.2.0-alpha02 introduced the MergeAdapter that has been renamed to ConcatAdapter with recyclerview:1.2.0-alpha04.
This RecyclerView Adapter can combine multiple adapters linearly.

Something like:

FirstAdapter adapter1 = ...;
SecondAdapter adapter2 = ...;
ConcatAdapter merged = new ConcatAdapter(adapter1, adapter2);
recyclerView.setAdapter(mergedAdapter);

As part of this change the method getAdapterPosition() was deprecated because the name is confusing when adapters nest other adapters. Now you should use the method getBindingAdapterPosition() which returns the position in the specific adapter (bindingAdapter).

Also checking the source code of RecyclerView.ViewHolder:

    @Deprecated
    public final int getAdapterPosition() {
        return getBindingAdapterPosition();
    }

Instead the method getAbsoluteAdapterPosition() returns the Adapter position of the item with respect to the entire RecyclerView. If you are using a ConcatAdapter it is the position in the ConcatAdapter and not the position in the single bindingAdapter.

Just an example with 2 adapters:

enter image description here

More details are available in the official blog post.

like image 175
Gabriele Mariotti Avatar answered Oct 19 '22 06:10

Gabriele Mariotti