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