To trudna sytuacja, przepraszam, że dokumenty nie są wystarczające.
Gdy zmienia się zawartość adaptera (i wywołujesz notify***()
), RecyclerView żąda nowego układu. Od tego momentu, dopóki system układu nie zdecyduje się obliczyć nowego układu (<16 ms), położenie układu i położenie adaptera mogą nie pasować, ponieważ układ nie odzwierciedla jeszcze zmian adaptera.
W twoim przypadku, ponieważ twoje dane są powiązane z zawartością twojego adaptera (i zakładam, że dane są zmieniane w tym samym czasie ze zmianami adaptera), powinieneś używać adapterPosition
.
Uważaj jednak, jeśli dzwonisz notifyDataSetChanged()
, ponieważ unieważnia to wszystko, RecyclerView nie wie, że pozycja adaptera ViewHolder do czasu obliczenia następnego układu. W takim przypadku getAdapterPosition()
zwróci RecyclerView#NO_POSITION
( -1
).
Ale powiedzmy, że jeśli zadzwoniłeś notifyItemInserted(0)
, getAdapterPosition()
ViewHolder, który był poprzednio na pozycji 0
, zacznie 1
natychmiast wracać . Tak długo, jak wysyłasz szczegółowe zdarzenia powiadomień, zawsze jesteś w dobrym stanie (znamy położenie adaptera, mimo że nowy układ nie został jeszcze obliczony).
Inny przykład, jeśli robisz coś po kliknięciu przez użytkownika, jeśli getAdapterPosition()
zwraca NO_POSITION
, najlepiej zignorować to kliknięcie, ponieważ nie wiesz, co kliknął użytkownik (chyba że masz inny mechanizm, np. Stabilne identyfikatory do wyszukiwania pozycji).
Edytuj, gdy pozycja układu jest dobra
Powiedzmy, że używasz LinearLayoutManager
i chcesz uzyskać dostęp do ViewHolder nad aktualnie klikniętym elementem. W takim przypadku powinieneś użyć pozycji układu, aby uzyskać powyższy element.
mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)
Musisz użyć pozycji układu, ponieważ pasuje ona do tego, co użytkownik obecnie widzi na ekranie.