Ответ 1
Это сложная ситуация, извините, что документов недостаточно.
Когда изменяется содержимое адаптера (и вы вызываете notify***()
), RecyclerView запрашивает новый макет. С этого момента, пока система макета не решит рассчитать новый макет (< 16 мс), расположение макета и позиция адаптера могут не совпадать, поскольку макет еще не изменил изменения адаптера.
В вашем случае использования, так как ваши данные связаны с содержимым вашего адаптера (и я предполагаю, что данные будут изменены одновременно с изменениями адаптера), вы должны использовать adapterPosition
.
Будьте осторожны, если вы вызываете notifyDataSetChanged()
, потому что он делает недействительным все, RecyclerView не знает, что позиция адаптера ViewHolder до вычисления следующего макета. В этом случае getAdapterPosition()
вернет RecyclerView#NO_POSITION
(-1
).
Но скажем, если вы вызвали notifyItemInserted(0)
, getAdapterPosition()
из ViewHolder, который ранее находился в позиции 0
, немедленно вернул 1
. Таким образом, пока вы отправляете подробные уведомления о событиях, вы всегда в хорошем состоянии (мы знаем положение адаптера, даже если новый макет еще не рассчитан).
Другой пример: если вы делаете что-то на клике пользователя, если getAdapterPosition()
возвращает NO_POSITION
, лучше игнорировать этот клик, потому что вы не знаете, какой пользователь нажал (если у вас нет другого механизма, например, стабильного ids для поиска элемента).
Изменить, когда позиция макета хорошая
Предположим, вы используете LinearLayoutManager
и хотите получить доступ к ViewHolder над текущим кликом. В этом случае вы должны использовать расположение макета, чтобы получить элемент выше.
mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)
Вы должны использовать расположение макета, так как оно соответствует тому, что пользователь видит на экране.