Eu tenho um RecyclerView que carrega alguns dados da API, inclui um url de imagem e alguns dados, e eu uso o networkImageView para carregar a imagem lentamente.
@Override
public void onResponse(List<Item> response) {
mItems.clear();
for (Item item : response) {
mItems.add(item);
}
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
Aqui está a implementação para o adaptador:
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
if (isHeader(position)) {
return;
}
// - get element from your dataset at this position
// - replace the contents of the view with that element
MyViewHolder holder = (MyViewHolder) viewHolder;
final Item item = mItems.get(position - 1); // Subtract 1 for header
holder.title.setText(item.getTitle());
holder.image.setImageUrl(item.getImg_url(), VolleyClient.getInstance(mCtx).getImageLoader());
holder.image.setErrorImageResId(android.R.drawable.ic_dialog_alert);
holder.origin.setText(item.getOrigin());
}
O problema é que quando atualizamos no recyclerView, ele fica ofuscado por um tempo muito curto no início, o que parece estranho.
Em vez disso, usei GridView / ListView e funcionou como esperado. Não houve cegueira.
configuração para RecycleView em onViewCreated of my Fragment
:
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
mGridLayoutManager = (GridLayoutManager) mRecyclerView.getLayoutManager();
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return mAdapter.isHeader(position) ? mGridLayoutManager.getSpanCount() : 1;
}
});
mRecyclerView.setAdapter(mAdapter);
Alguém enfrenta esse problema? Qual seria a razão?
Respostas:
Tente usar IDs estáveis em seu RecyclerView.Adapter
setHasStableIds(true)
e substituirgetItemId(int position)
.Depois
notifyDataSetChanged()
, sem IDs estáveis , ViewHolders geralmente não são atribuídos às mesmas posições. Esse foi o motivo de piscar no meu caso.Você pode encontrar uma boa explicação aqui.
fonte
De acordo com esta página de problema .... é a animação de mudança de item de Recycleview padrão ... Você pode desligá-la .. tente isto
Mudança na última versão
Citado do blog do desenvolvedor Android :
fonte
Isso simplesmente funcionou:
fonte
code
ItemAnimator animator = recyclerView.getItemAnimator (); if (instância do animador de SimpleItemAnimator) {((SimpleItemAnimator) animador) .setSupportsChangeAnimations (false); }code
Eu tenho o mesmo problema ao carregar a imagem de alguns urls e, em seguida, pisca imageView. Resolvido usando
ao invés de
o que evita recarregar os dados antigos inalterados.
fonte
tente isso para desativar a animação padrão
esta é a nova maneira de desabilitar a animação desde o suporte para Android 23
esta forma antiga funcionará para a versão mais antiga da biblioteca de suporte
fonte
Supondo que
mItems
seja a coleção que o sustentaAdapter
, por que você está removendo tudo e adicionando novamente? Basicamente, você está dizendo a ele que tudo mudou, então o RecyclerView vincula novamente todas as visualizações, então presumo que a biblioteca de imagens não o manipule adequadamente, onde ainda redefine a visualização, embora seja o mesmo URL da imagem. Talvez eles tenham alguma solução pronta para o AdapterView para que funcione bem no GridView.Em vez de chamar, o
notifyDataSetChanged
que causará a religação de todas as visualizações, chame eventos de notificação granular (notificação adicionada / removida / movida / atualizada) para que o RecyclerView religue apenas as visualizações necessárias e nada pisque.fonte
Recyclerview usa DefaultItemAnimator como seu animador padrão. Como você pode ver no código abaixo, eles mudam o alfa do portador de visualização quando o item muda:
Eu queria reter o resto das animações, mas remover a "cintilação", então clonuei DefaultItemAnimator e removi as 3 linhas alfa acima.
Para usar o novo animador, basta chamar setItemAnimator () em seu RecyclerView:
fonte
No Kotlin, você pode usar 'extensão de classe' para RecyclerView:
fonte
Ei @Ali, pode ser o replay atrasado. Eu também enfrentei esse problema e resolvi com a solução abaixo, pode ajudar você, verifique.
A classe LruBitmapCache.java é criada para obter o tamanho do cache de imagem
VolleyClient.java singleton [estende o aplicativo] adicionado abaixo do código
no construtor da classe singleton VolleyClient adicione o trecho abaixo para inicializar o ImageLoader
Criei o método getLruBitmapCache () para retornar LruBitmapCache
Espero que ajude você.
fonte
para mim
recyclerView.setHasFixedSize(true);
funcionoufonte
No meu caso, nenhum dos itens acima nem as respostas de outras questões stackoverflow com os mesmos problemas funcionaram.
Bem, eu estava usando animação personalizada cada vez que o item era clicado, para o qual eu estava chamando notificarItemChanged (posição int, carga útil do objeto) para passar carga útil para minha classe CustomAnimator.
Observe, há 2 métodos onBindViewHolder (...) disponíveis no Adaptador RecyclerView. O método onBindViewHolder (...) com 3 parâmetros sempre será chamado antes do método onBindViewHolder (...) com 2 parâmetros.
Geralmente, sempre substituímos o método onBindViewHolder (...) com 2 parâmetros e a principal raiz do problema era que eu estava fazendo o mesmo, pois cada vez que notificarItemChanged (...) for chamado, nosso método onBindViewHolder (...) irá ser chamado, no qual estava carregando minha imagem no ImageView usando o Picasso, e por isso estava carregando novamente independentemente de ser da memória ou da internet. Até o carregamento, ele me mostrava a imagem do placeholder, que era o motivo de piscar por 1 segundo sempre que clicava no itemview.
Posteriormente, também substituo outro método onBindViewHolder (...) com 3 parâmetros. Aqui, eu verifico se a lista de cargas úteis está vazia e, em seguida, retorno a implementação da superclasse desse método; caso contrário, se houver cargas úteis, estou apenas definindo o valor alfa do itemView do titular como 1.
E sim, consegui a solução para o meu problema depois de perder um dia inteiro, infelizmente!
Este é meu código para os métodos onBindViewHolder (...):
onBindViewHolder (...) com 2 parâmetros:
onBindViewHolder (...) com 3 parâmetros:
Aqui está o código do método que eu estava chamando em onClickListener do itemView do viewHolder em onCreateViewHolder (...):
Nota: Você pode obter esta posição chamando o método getAdapterPosition () de seu viewHolder de onCreateViewHolder (...).
Também substituí o método getItemId (int position) da seguinte maneira:
e chamei
setHasStableIds(true);
meu objeto adaptador em atividade.Espero que isso ajude se nenhuma das respostas acima funcionar!
fonte
No meu caso, havia um problema muito mais simples, mas pode ser muito parecido com o problema acima. Eu tinha convertido um ExpandableListView em um RecylerView com Groupie (usando o recurso ExpandableGroup do Groupie). Meu layout inicial tinha uma seção como esta:
Com layout_height definido como "wrap_content", a animação do grupo expandido para o grupo recolhido parecia que iria piscar, mas na verdade estava apenas animando da posição "errada" (mesmo depois de tentar a maioria das recomendações neste tópico).
De qualquer forma, simplesmente alterar layout_height para match_parent assim resolveu o problema.
fonte
Eu tive um problema semelhante e isso funcionou para mim Você pode chamar este método para definir o tamanho do cache de imagem
fonte
para meu aplicativo, tive alguns dados alterados, mas não queria que toda a visualização piscasse.
Eu resolvi isso apenas diminuindo a visão antiga em 0,5 alfa e iniciando a nova visualização em 0,5. Isso criou uma transição de desbotamento mais suave sem fazer a visualização desaparecer completamente.
Infelizmente, por causa de implementações privadas, não pude criar uma subclasse de DefaultItemAnimator para fazer essa alteração, então tive que clonar o código e fazer as seguintes alterações
em animateChange:
em animateChangeImpl:
fonte
Usar métodos de reciclagem apropriados para atualizar as visualizações resolverá esse problema
Primeiro, faça alterações na lista
Em seguida, notifique usando
Espero que isso ajude !!
fonte
Tente usar o stableId na visualização do reciclador. O artigo a seguir explica brevemente isso
https://medium.com/@hanru.yeh/recyclerviews-views-are-blinking-when-notifydatasetchanged-c7b76d5149a2
fonte
Solução Kotlin:
fonte