Esta é uma situação complicada, desculpe que os documentos não são suficientes.
Quando o conteúdo do adaptador muda (e você chama notify***()
), o RecyclerView solicita um novo layout. A partir desse momento, até que o sistema de layout decida calcular um novo layout (<16 ms), a posição do layout e a posição do adaptador podem não corresponder porque o layout ainda não refletiu as alterações do adaptador.
Em seu caso de uso, como seus dados estão relacionados ao conteúdo do adaptador (e presumo que os dados sejam alterados ao mesmo tempo com as alterações do adaptador), você deve usar adapterPosition
.
Porém, tenha cuidado, se você estiver chamando notifyDataSetChanged()
, porque isso invalida tudo, o RecyclerView não sabe a posição do adaptador do ViewHolder até que o próximo layout seja calculado. Nesse caso, getAdapterPosition()
irá retornar RecyclerView#NO_POSITION
( -1
).
Mas digamos que se você chamou notifyItemInserted(0)
, o getAdapterPosition()
de ViewHolder que estava anteriormente na posição 0
começará a retornar 1
imediatamente. Portanto, enquanto você está despachando eventos de notificação granulares, você está sempre em bom estado (sabemos a posição do adaptador, embora o novo layout ainda não tenha sido calculado).
Outro exemplo, se você estiver fazendo algo no clique do usuário, se getAdapterPosition()
retornar NO_POSITION
, é melhor ignorar esse clique porque você não sabe o que o usuário clicou (a menos que você tenha algum outro mecanismo, por exemplo, ids estáveis para pesquisar o item).
Editar para quando a posição do layout for boa
Vamos dizer que você está usando LinearLayoutManager
e deseja acessar o ViewHolder acima do item clicado no momento. Nesse caso, você deve usar a posição do layout para obter o item acima.
mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)
Você deve usar a posição do layout porque corresponde ao que o usuário está vendo na tela.
Em ordem a discutir a diferença (s) de
getAdapterPosition()
,getLayoutPosition()
, e tambémposition
; notaríamos os casos abaixo:1.
position
argumento noonBindViewHolder()
método:Podemos usar o
position
para vincular dados à visualização e não há problema em usar oposition
argumento para fazer isso, mas não é permitido usar oposition
argumento para lidar com cliques do usuário e, se você o usou, verá um aviso informando "não tratarposition
como consertar e usarholder.getAdapterPosition()
lugar ".2
getAdapterPosition()
.:Este método sempre consiste na posição atualizada do adaptador do
holder
. Isso significa que sempre que você clica em um item, você pergunta ao adaptador sobre eleposition
. portanto, você obterá a posição mais recente deste item em termos da lógica do adaptador.3 -
getLayoutPosition()
.:Às vezes, é necessário encontrar o
position
em termos do layout atualizado (o último layout passado que o usuário está vendo agora), por exemplo: Se o usuário solicitar o terceiro,position
ele pode ver e você usarswipe
/dismiss
para itens ou aplicar qualquer animação ou decorações para itens que será melhor usar emgetLayoutPosition()
vez degetAdapterPosition()
, porque você sempre terá certeza de que está lidando com a posição dos itens em termos do último layout aprovado.Para obter mais informações sobre isso; veja aqui . . .
fonte