C'est une situation délicate, désolé que les documents ne soient pas suffisants.
Lorsque le contenu de l'adaptateur change (et que vous appelez notify***()
), RecyclerView demande une nouvelle disposition. À partir de ce moment, jusqu'à ce que le système de mise en page décide de calculer une nouvelle mise en page (<16 ms), la position de mise en page et la position de l'adaptateur peuvent ne pas correspondre car la mise en page n'a pas encore reflété les changements d'adaptateur.
Dans votre cas d'utilisation, puisque vos données sont liées au contenu de votre adaptateur (et je suppose que les données sont modifiées en même temps avec les changements d'adaptateur), vous devriez utiliser adapterPosition
.
Attention cependant, si vous appelez notifyDataSetChanged()
, car il invalide tout, RecyclerView ne sait pas que la position de l'adaptateur de ViewHolder jusqu'à ce que la disposition suivante soit calculée. Dans ce cas, getAdapterPosition()
retournera RecyclerView#NO_POSITION
(-1
).
Mais disons que si vous avez appelé notifyItemInserted(0)
, le getAdapterPosition()
de ViewHolder qui était auparavant à la position 0
commencera à revenir 1
immédiatement. Ainsi, tant que vous distribuez des événements de notification granulaires, vous êtes toujours en bon état (nous connaissons la position de l'adaptateur même si la nouvelle mise en page n'est pas encore calculée).
Un autre exemple, si vous faites quelque chose sur le clic de l'utilisateur, s'il getAdapterPosition()
retourne NO_POSITION
, il est préférable d'ignorer ce clic parce que vous ne savez pas sur quel utilisateur a cliqué (sauf si vous avez un autre mécanisme, par exemple des identifiants stables pour rechercher l'élément).
Modifier pour lorsque la position de la disposition est bonne
Disons que vous utilisez LinearLayoutManager
et souhaitez accéder au ViewHolder au-dessus de l'élément actuellement cliqué. Dans ce cas, vous devez utiliser la position de mise en page pour obtenir l'élément ci-dessus.
mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)
Vous devez utiliser la position de la mise en page car elle correspond à ce que l'utilisateur voit actuellement à l'écran.
Afin de soutenir la différence (s) de
getAdapterPosition()
,getLayoutPosition()
et égalementposition
; nous remarquerons les cas ci-dessous:1.
position
argument dans laonBindViewHolder()
méthode:Nous pouvons utiliser
position
pour lier les données à la vue et il est correct d'utiliser l'position
argument pour ce faire, mais ce n'est pas bien d'utiliser l'position
argument pour gérer les clics des utilisateurs et si vous l'avez utilisé, vous verrez un avertissement vous indiquant "ne pas traiterposition
comme fixe et utiliser à laholder.getAdapterPosition()
place ".2
getAdapterPosition()
.:Cette méthode consiste toujours en la position de l'adaptateur mis à jour du
holder
. Cela signifie que chaque fois que vous avez cliqué sur un élément, vous demandez à l'adaptateur à ce sujetposition
. vous obtiendrez donc la dernière position de cet élément en termes de logique d'adaptateur.3
getLayoutPosition()
.:Parfois, il est nécessaire de trouver le
position
en termes de mise en page mise à jour (la dernière mise en page passée que l'utilisateur voit maintenant), par exemple: Si l'utilisateur demande la troisième,position
il peut voir et vous utilisezswipe
/dismiss
pour des éléments ou appliquez une animation ou des décorations pour les objets, il sera préférable d'utiliser à lagetLayoutPosition()
place degetAdapterPosition()
, car vous serez toujours sûr que vous traitez avec la position des éléments en termes de la dernière mise en page passée.Pour plus d'informations à ce sujet; voir ici . . .
la source