我們在使用RecyclerView的時候赘来,總是不可避免的獲取其ItemView的位置來實現(xiàn)各種各樣的需求:
RecyClerView也提供了獲取位置的幾種方法,
onBindViewHolder(holder:? ViewHolder, position: Int)
getAdapterPosition
getBindingAdapter
getAbslouteAdapterPosition
getLayoutPosition
通常我們會在onBindViewHolder中通過position參數(shù)綁定數(shù)據(jù)和視圖怔接,如果我們在這里使用position參數(shù)來處理點擊事件會出現(xiàn)一些問題,
我們在布局加上一個刪除列表的第一項數(shù)據(jù)功能稀轨。
這時候點擊每一項彈出對應的position
我連續(xù)4次點擊"刪除第一項"按鈕扼脐,這時候點擊"第4"這一個Itme時候,應該要更新positon彈出點擊了0 但是彈出點擊了4.說明還是以前的位置。這就是在onBindViewHolder中直接使用position參數(shù)設置點擊事件可能引發(fā)的問題瓦侮。
其實原因很簡單:使用notifyItem一系列的方法來刪除艰赞,添加,更改我們RecyclerView的數(shù)據(jù)的任何一條數(shù)據(jù)肚吏,RecyclerView并不會調(diào)用所有Item的onBindViewHolder方法更新Item的位置方妖,它只會更新notifyItem的位置就導致了顯式的數(shù)據(jù)和實際數(shù)據(jù)的Position對應不上的問題。
官網(wǎng)建議使用getBindingAdapterPosition罚攀。
getAdapterPosition已經(jīng)廢棄了党觅,這個方法在 Adapter 嵌套Adapter 的情況下會帶來歧義
接下來看下getAbsoluteAdaptionPosition?
這個方法是相對于RecyclerView的。
MergeAdapter這個在recyclerView1.2.0之后叫ContactAdapter坞生,可以連接多個Adapter仔役。相當于以前多種樣式布局getItemViewType方案
getBindingAdapterPosition將會返回該ViewHolder相對于它綁定的Adapter的位置
getAbsoluteAdapterPosition將會返回該ViewHolder相對于RecyclerView的位置。
下面我們再來聊一下getLayoutPosition
顧名思義就是獲取該ViewHolder在實際布局中的位置是己, RecyclerView?將布局策略委托給LayoutManager布局管理器又兵。當開發(fā)者調(diào)用notifyData一系列方法通知RecyclerView刷新UI時,Ui并不會馬上刷新卒废,而是通過布局管理器更新布局沛厨,這個過程就需要時間上的等待,當然這個等待時間很小(不超過16ms的一般)摔认,從感官上看getLayoutposition和getAbsoluteAdapterPosition十分接近逆皮,
getAbsoluteAdapterPosition將會返回該ViewHolder相對于RecyclerView的位置。
而getLayoutposition返回的是該ViewHolder相對于ViewHolder相對于RecyclerView實際布局的絕對位置参袱。
對于Layout的position电谣,在notifyItemInserted之后,Layout不能馬上獲取到新的position抹蚀,因為布局還沒更新(需要<16ms的時間刷新視圖)剿牺。
所以對于上面那個場景,我們在獲取用戶點擊位置的時候环壤,使用getLayoutPosition可能效果更好晒来,這樣可以確保用戶點擊的始終是他看到的那個數(shù)據(jù)。