RecyclerView中不同的位置概念可以幫助你更有效地處理數據項和用戶交互
getAdapterPosition
getAdapterPosition()是RecyclerView.ViewHolder類的一個方法,用于獲取與該ViewHolder關聯的項目在適配器(Adapter)中的位置。在數據綁定、點擊事件處理、以及需要知道項目在列表或網格中具體位置的其他場景中非常有用。
從RecyclerView的onBindViewHolder、onClick或其他與ViewHolder相關的回調中使用getAdapterPosition方法時,會返回與當前ViewHolder綁定的數據項在適配器中的索引。
- 「數據變更」:在getAdapterPosition()被調用之前,適配器中的數據發生了變更(例如,通過notifyDataSetChanged(), notifyItemInserted(), notifyItemRemoved(), 等方法),ViewHolder可能會因為回收和重用而與實際位置不同步,返回的位置可能不再反映當前UI狀態。
- 「ViewHolder的復用」:RecyclerView為了提高性能,會復用ViewHolder實例來綁定不同的數據項。即使ViewHolder被重用于表示新的數據項,getAdapterPosition()也會返回新的數據項在適配器中的位置。
- 「無效位置」:ViewHolder不再與任何數據項關聯(例如,由于列表項被完全移除或滾動出屏幕),getAdapterPosition()可能會返回RecyclerView.NO_POSITION(-1)。在使用getAdapterPosition()之前,最好檢查返回值是否有效。
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int adapterPosition = holder.getAdapterPosition();
if (adapterPosition != RecyclerView.NO_POSITION) {
// 處理點擊事件,使用adapterPosition作為索引
}
}
});
}
圖片
遺憾的是getAdapterPosition方法標記為過期廢棄了。
getBindindAdapterPosition
getBindingAdapterPosition() 是 RecyclerView.ViewHolder 類的一個方法,與 getAdapterPosition() 類似,但用途上略有不同。
RecyclerView 通過 LayoutManager 來確定每個項目的位置和大小,并使用 Adapter 來提供數據和將數據綁定到視圖上。為了優化性能,RecyclerView 會復用 ViewHolder 對象,這意味著同一個 ViewHolder 實例可能會被用來綁定不同位置上的數據。
- 「getAdapterPosition()」
返回的是當前 ViewHolder 最后綁定數據時的適配器位置(在數據最后一次變化后的位置)。
如果在數據變化后,ViewHolder 沒有被重新綁定,返回的可能是之前的位置。
- 「getBindingAdapterPosition()」
只在 onBindViewHolder() 方法的上下文中有效。
返回的是當前正在綁定到 ViewHolder 的數據項在適配器中的位置。
在 onBindViewHolder() 方法之外調用此方法可能會返回 RecyclerView.NO_POSITION(-1),此時 ViewHolder 可能沒有綁定到任何數據項。
getAbsoluteAdapterPosition
getAbsoluteAdapterPosition()是RecyclerView.ViewHolder的一個方法,用于獲取與ViewHolder關聯的項在適配器中的絕對位置。
- 當RecyclerView的適配器是嵌套的時候,使用getAbsoluteAdapterPosition()可以獲取到嵌套的RecyclerView中項在外部RecyclerView適配器中的絕對位置。
- 與getAdapterPosition()相比,getAbsoluteAdapterPosition()考慮了所有嵌套的RecyclerView層級,并返回了一個全局的、唯一的、不受層級影響的位置。
1.「返回值」
如果ViewHolder當前與某個項關聯,返回一個大于或等于0的整數,表示該項在適配器中的絕對位置。
如果ViewHolder當前沒有與任何項關聯(例如,因為該項已經從列表中移除或者ViewHolder正在被回收),返回RecyclerView.NO_POSITION,其值為-1。
2.「注意事項」
getAbsoluteAdapterPosition()考慮了嵌套的RecyclerView層級,返回的位置可能與直接通過getAdapterPosition()獲得的位置不同。
當處理嵌套RecyclerView的交互或數據時,使用getAbsoluteAdapterPosition()可以確保獲取到的是全局的、唯一的位置。
getAbsoluteAdapterPosition()也可能在ViewHolder被回收或沒有與任何項關聯時返回RecyclerView.NO_POSITION,在使用其返回值之前應進行檢查。
getLayoutPosition
getLayoutPosition()是RecyclerView.ViewHolder類的一個方法,用于獲取ViewHolder在當前的布局中的位置。這個位置是基于當前屏幕上可見的項和RecyclerView的滾動狀態來確定的。
1.「使用場景」
當需要知道ViewHolder在屏幕上的當前位置(而不僅僅是它在適配器中的位置)時,可以使用getLayoutPosition()。
與getAdapterPosition()不同,getLayoutPosition()返回的是ViewHolder在當前可見項列表中的位置,它可能因滾動而發生變化。
2.「返回值」
如果ViewHolder當前與某個項關聯并且在屏幕上可見,返回一個大于或等于0的整數,表示該項在當前布局中的位置。
如果ViewHolder當前沒有與任何項關聯(例如,因為該項已經從列表中移除或者ViewHolder正在被回收),返回RecyclerView.NO_POSITION,值為-1。
3.「注意事項」getLayoutPosition()返回的位置是基于當前屏幕上可見的項和RecyclerView的滾動狀態來確定的。如果滾動了RecyclerView,即使項的適配器位置沒有變化,它的布局位置也可能會變化。
如果ViewHolder已經被RecyclerView回收或不再與任何項關聯,getLayoutPosition()將返回RecyclerView.NO_POSITION。
在大多數情況下,如果需要處理與項相關的數據或事件,并且不關心這些項在屏幕上的具體位置,使用Adapter相關的位置方法會更為合適。