Recyclerview do Android vs ListView com visualizador

148

Recentemente, deparei com o Android RecyclerViewlançado com o Android 5.0 e parece que RecyclerViewé apenas um tradicional encapsulado ListViewcom o padrão ViewHolder incorporado a ele, que promove a reutilização da visualização, em vez de criá-la sempre.

Quais são os outros benefícios do uso RecyclerView? Se ambos têm o mesmo efeito em termos de desempenho, por que alguém prefere o RecyclerView`?

Editar

Descobri que as pessoas fizeram perguntas semelhantes e as respostas não são conclusivas, adicionando-as aqui para manutenção de registros.

Recyclerview vs Listview

Devemos usar o RecyclerView para substituir o ListView?

Por que o RecyclerView não tem onItemClickListener ()? e Como o RecyclerView é diferente do Listview?

Mushtaq Jameel
fonte
4
Porque RecyclerViewé muito mais rápido e versátil com uma API muito melhor. Coisas como animar a adição ou remoção de itens já estão implementadas RecyclerViewsem que você precise fazer nada. Não há dúvida sobre isso, jogue o seu ListViewna lata de lixo, o RecyclerViewestá aqui para roubar o show.
Xaver Kapeller
4
Você pode associar um gerenciador de layout a um RecyclerView, para que não se limitem a listas de rolagem vertical. Essa é uma funcionalidade adicional bastante poderosa.
Alan
@ Alan - O que você quer dizer com "não limitado a listas de rolagem vertical"? Você está dizendo que o Recycle View também pode atuar como um "espaço reservado" para GridViews e ListViews?
Mushtaq Jameel
@XaverKapeller - Seria ótimo se você pudesse listar as diferenças entre os dois e responder à pergunta em vez de comentar, para que isso possa ajudar a mim e aos outros no futuro que possam estar se perguntando sobre a mesma coisa?
Mushtaq Jameel
@ Alan - Você poderia fornecer um pouco de detalhes sobre o que queria dizer e responder à pergunta em vez de comentar. Obrigado por reservar um tempo
Mushtaq Jameel

Respostas:

289

Com o advento do Android Lollipop, o RecyclerView fez o seu caminho oficialmente. O RecyclerView é muito mais poderoso, flexível e um grande aprimoramento sobre o ListView . Vou tentar dar uma visão detalhada sobre isso.

1) Padrão ViewHolder

Em um ListView, era recomendável usar o padrão ViewHolder, mas isso nunca era uma compulsão. No caso do RecyclerView, isso é obrigatório usando a classe RecyclerView.ViewHolder . Essa é uma das principais diferenças entre o ListView e o RecyclerView.

Isso torna as coisas um pouco mais complexas no RecyclerView, mas muitos problemas que enfrentamos no ListView são resolvidos com eficiência.

2) LayoutManager

Esse é outro grande aprimoramento trazido para o RecyclerView. Em um ListView, o único tipo de exibição disponível é o ListView vertical. Não existe uma maneira oficial de implementar um ListView horizontal.

Agora, usando um RecyclerView, podemos ter um

i) LinearLayoutManager - que suporta listas verticais e horizontais,

ii) StaggeredLayoutManager - que suporta o Pinterest como listas escalonadas,

iii) GridLayoutManager - que suporta a exibição de grades como visto nos aplicativos da Galeria.

E o melhor é que podemos fazer tudo isso dinamicamente como queremos.

3) Animador de itens

Faltam listViews no suporte a boas animações, mas o RecyclerView traz uma dimensão totalmente nova para ele. Usando a classe RecyclerView.ItemAnimator , animar as visualizações se torna muito fácil e intuitivo.

4) Item Decoração

No caso de ListViews, nunca foi fácil decorar itens dinamicamente, como adicionar bordas ou divisórias. Porém, no caso do RecyclerView, a classe RecyclerView.ItemDecorator oferece grande controle aos desenvolvedores, mas torna as coisas um pouco mais demoradas e complexas.

5) OnItemTouchListener

A interceptação de cliques em itens em um ListView era simples, graças à sua interface AdapterView.OnItemClickListener . Mas o RecyclerView fornece muito mais poder e controle aos seus desenvolvedores pelo RecyclerView.OnItemTouchListener ( não é mais suportado, consulte o AndroidX ), mas complica um pouco as coisas para o desenvolvedor.

Em palavras simples, o RecyclerView é muito mais personalizável que o ListView e oferece muito controle e poder aos seus desenvolvedores.

Aritra Roy
fonte
34
Boa resposta. Algumas vantagens adicionais: O RecyclerView prepara a visualização logo à frente e atrás das entradas visíveis, o que é ótimo se você estiver buscando bitmaps em segundo plano. O desempenho é muito mais rápido, especialmente se você usar RecyclerView.setHasFixedSize. O antigo ListView é baseado na premissa de que não há como pré-calcular ou armazenar em cache o tamanho das entradas na lista, o que causa complicações insanas ao rolar e executar o layout. Demora um pouco para se acostumar, mas, quando o fizer, nunca mais voltará.
Robin Davies
@RobinDavies Excellent point. Obrigado por informar. Mas não fará sentido se os tamanhos dos itens forem diferentes.
Aritra Roy
Suportes @AritraRoy Recyclerview em Lollipop ou api 14+ (android 4+) também .... como eu li "depois pirulito: na maioria dos lugares?
Animesh Mangla
2
Ei, Aritra, Ao comparar com o ListView, se o ListView também usa o ViewHolder Pattern, qual deles age com mais eficiência? ? Será RecylerView o melhor, ao usar fps ou outra algum critério semelhante thx ~
RxRead
@RxRead: Veja o comentário de Robin, ele diferencia o RecyclerView Vs ListView do padrão de suporte de exibição com base no desempenho.
Parag Kadam 05/09
10

A outra vantagem do uso RecycleViewé a animação, que pode ser feita em duas linhas de código

RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator();
        recyclerView.setItemAnimator(itemAnimator);

Mas o widget ainda é bruto, por exemplo, você não pode criar cabeçalho e rodapé .

Etun
fonte
5
E você nunca será capaz de criar cabeçalho e rodapé nesse sentido. Eles são apenas outros tipos de exibição no seu adaptador. A exibição em lista envolve seu adaptador HeaderViewListAdaptere adiciona suporte ao cabeçalho em segundo plano. Com RecyclerViewvocê é quem está no controle.
Eugen Pechanec
RecyclerView usa um DefaultItemAnimator por padrão. Então, por que você usou esse código?
Athira Reddy
9

Tudo bem, cavando um pouco e encontrei essas jóias do artigo de Bill Philips sobreRecycleView

O RecyclerView pode fazer mais que o ListView, mas a própria classe RecyclerView tem menos responsabilidades que o ListView. Pronto para uso, o RecyclerView não:

  • Posicionar itens na tela
  • Animar visualizações
  • Manipule todos os eventos de toque além da rolagem

Todo esse material foi inserido no ListView, mas o RecyclerView usa classes de colaborador para executar esses trabalhos.

Os ViewHolders que você cria também são mais robustos. Eles subclasses RecyclerView.ViewHolder, que tem vários métodos RecyclerView usados. ViewHolderssaiba a qual posição eles estão vinculados no momento e quais IDs de itens (se você tiver esses). No processo, ViewHolder foi cavaleiro. Costumava ser o trabalho do ListView manter toda a exibição do item, e ViewHoldermanter apenas pequenas partes dela.

Agora, o ViewHolder mantém tudo isso no ViewHolder.itemView campo, que é designado no construtor do ViewHolder para você.

Mushtaq Jameel
fonte
4

Mais do artigo de Bill Phillip (vá ler!), Mas achei importante ressaltar o seguinte.

No ListView, havia alguma ambiguidade sobre como lidar com eventos de clique: as visualizações individuais devem lidar com esses eventos ou o ListView deve lidar com eles por meio do OnItemClickListener? No RecyclerView, no entanto, o ViewHolder está em uma posição clara para atuar como um objeto controlador de nível de linha que lida com esses tipos de detalhes.

Vimos anteriormente que o LayoutManager manipulava as vistas de posicionamento e o ItemAnimator manipulava as animações. ViewHolder é a última peça: é responsável por manipular quaisquer eventos que ocorram em um item específico exibido pelo RecyclerView.

Jaison Brooks
fonte
2

Usei um ListViewcarregador de imagem Glide, com aumento de memória. Então substituí o ListViewcom um RecyclerView. Não é apenas mais difícil na codificação, mas também leva a um maior uso de memória que a ListView. Pelo menos no meu projeto.

Em outra atividade, usei uma lista complexa com EditText's. Em alguns deles, um método de entrada pode variar, e também TextWatcherpode ser aplicado. Se eu usasse a ViewHolder, como poderia substituir a TextWatcherdurante a rolagem? Então, eu usei um ListViewsem a ViewHolder, e funciona.

CoolMind
fonte
Eu usei um ListView sem um ViewHolder e funciona. péssima idéia ... como eu poderia substituir um TextWatcher durante a rolagem? não há necessidade de substituí-lo ... apenas TextWacher deve colocar os dados em um recipiente diferente depois reutilizando ... e isso pode ser feito muito fácil
Selvin
@ Selvin, obrigado pela sua opinião. Agora não posso editar esse projeto. Havia vários TextWatchers na tela. Provavelmente você está certo, mas não posso dar uma olhada.
CoolMind
1

Reutiliza células ao rolar para cima / para baixo - isso é possível com a implementação do View Holder no adaptador listView, mas era algo opcional, enquanto no RecycleView é a maneira padrão de gravar o adaptador.

Separa a lista de seu contêiner - para que você possa colocar itens da lista facilmente em tempo de execução nos diferentes contêineres (linearLayout, gridLayout) com a configuração LayoutManager.

Exemplo:

mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//or
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
  • Anima ações de lista comuns.

  • As animações são dissociadas e delegadas ItemAnimator.

Há mais sobre o RecyclerView, mas acho que esses pontos são os principais.

LayoutManager

i) LinearLayoutManager - que suporta listas verticais e horizontais,

ii) StaggeredLayoutManager - que suporta o Pinterest como listas escalonadas,

iii) GridLayoutManager - que suporta a exibição de grades como visto nos aplicativos da Galeria.

E o melhor é que podemos fazer tudo isso dinamicamente como queremos.

Keshav Gera
fonte
1

1. Exibir titulares

No ListView, definir titulares de exibição era uma abordagem sugerida para manter referências para exibições. Mas não foi uma compulsão. Embora, ao não fazer isso, o ListView usado mostre dados obsoletos. Outra grande desvantagem de não usar detentores de visualizações pode levar a uma operação pesada de encontrar visualizações por IDs todas as vezes. O que resultou em ListViews atrasados.

Esse problema foi resolvido no RecylerView pelo uso da classe RecyclerView.ViewHolder. Essa é uma das principais diferenças no RecyclerView e no ListView. Ao implementar um RecyclerView, essa classe é usada para definir um objeto ViewHolder que é usado pelo adaptador para vincular o ViewHolder a uma posição. Outro ponto a ser observado aqui é que, ao implementar o adaptador para o RecyclerView, é obrigatório fornecer um ViewHolder. Isso torna a implementação um pouco complexa, mas resolve os problemas enfrentados no ListView.

2. Gerenciador de Layout

Ao falar de ListViews, apenas um tipo de ListView está disponível, ou seja, o ListView vertical. Você não pode implementar um ListView com rolagem horizontal. Eu sei que existem maneiras de implementar um pergaminho horizontal, mas acredite, ele não foi projetado para funcionar dessa maneira.

Mas agora, quando analisamos o Android RecyclerView vs ListView, também temos suporte para coleções horizontais. Na verdade, ele suporta vários tipos de listas. Para oferecer suporte a vários tipos de listas, ele usa a classe RecyclerView.LayoutManager. Isso é algo novo que o ListView não possui. O RecyclerView suporta três tipos de gerenciadores de layout predefinidos:

LinearLayoutManager - Este é o gerenciador de layout mais usado no caso do RecyclerView. Com isso, podemos criar listas de rolagem horizontais e verticais. StaggeredGridLayoutManager - Através desse gerenciador de layout, podemos criar listas escalonadas. Assim como a tela do Pinterest. GridLayoutManager - Esse gerenciador de layout pode ser usado para exibir grades, como qualquer galeria de imagens.

3. Animador de Itens

As animações em uma lista são uma dimensão totalmente nova, com inúmeras possibilidades. Em um ListView, como tal, não há disposições especiais pelas quais se possa animar, adicionar ou excluir itens. Mais tarde, com a evolução do Android, o ViewPropertyAnimator foi sugerido por Chet Haase, do Google, neste tutorial em vídeo para animações no ListView.

Por outro lado, comparando o Android RecyclerView vs ListView, ele possui a classe RecyclerView.ItemAnimator para lidar com animações. Através dessa classe, é possível definir animações personalizadas para eventos de adição, exclusão e movimentação de itens. Também fornece um DefaultItemAnimator, caso você não precise de personalizações.

4. Adaptador

Os adaptadores ListView eram simples de implementar. Eles tinham um método principal getView, onde toda a mágica costumava acontecer. Onde as vistas estavam vinculadas a uma posição. Além disso, eles costumavam ter um método interessante registerDataSetObserver, em que é possível definir um observador diretamente no adaptador. Esse recurso também está presente no RecyclerView, mas a classe RecyclerView.AdapterDataObserver é usada para ele. Mas o ponto a favor do ListView é que ele suporta três implementações padrão de adaptadores:

ArrayAdapter CursorAdapter SimpleCursorAdapter Enquanto o adaptador RecyclerView, possui toda a funcionalidade que os adaptadores ListView tinham, exceto o suporte interno para cursores de banco de dados e ArrayLists. No RecyclerView.Adapter, a partir de agora, precisamos fazer uma implementação customizada para fornecer dados ao adaptador. Assim como um BaseAdapter faz para ListViews. Embora você queira saber mais sobre a implementação do adaptador RecyclerView, consulte o Exemplo do Android RecyclerView.

5. Notificando alterações nos dados

Ao trabalhar com um ListView, se o conjunto de dados for alterado, você deverá chamar o método notifyDataSetChanged do adaptador subjacente para atualizar os dados. Ou defina o método setNotifyOnChange como true, caso deseje chamar o método notifyDataSetChanged automaticamente. Mas em ambos os casos, o resultado é muito pesado na lista. Basicamente, atualiza as visualizações da lista.

Porém, pelo contrário, em um adaptador RecyclerView, se um único item ou um intervalo de itens tiver sido alterado, existem métodos para notificar a alteração adequadamente. Aqueles são notifyItemChanged e notifyItemRangeChanged respectivamente e muitos mais como:

notifyItemInsterted notifyItemMoved notifyItemRangeInsterted notifyItemRangeRemoved E é claro que possui o método original para atualizar a lista inteira, ou seja, notifyDataSetChanged que notifica a adaptação de todo o conjunto de dados alterado.

6. Item Decoração

Para exibir divisores personalizados em um ListView, é possível adicionar facilmente esses parâmetros no XML do ListView:

XHTML android: divider = "@ android: cor / transparente" android: dividerHeight = "5dp" 1 2 android: divider = "@ android: cor / transparente" android: dividerHeight = "5dp" A parte interessante sobre o Android RecyclerView é que, a partir de agora, não mostra um divisor entre os itens por padrão. Embora os caras do Google devam ter deixado isso de lado para personalização, intencionalmente. Mas isso aumenta muito o esforço de um desenvolvedor. Se você deseja adicionar um divisor entre itens, pode ser necessário fazer uma implementação personalizada usando a classe RecyclerView.ItemDecoration.

Ou você pode aplicar um hack usando esse arquivo de amostras oficiais: DividerItemDecoration.java

7. OnItemTouchListener

As listviews costumavam ter uma implementação simples para a detecção de cliques, ou seja, pelo uso da interface AdapterView.OnItemClickListener.

Por outro lado, a interface RecyclerView.OnItemTouchListener é usada para detectar eventos de toque no Android RecyclerView. Isso complica um pouco a implementação, mas dá um controle maior ao desenvolvedor para interceptar eventos de toque. A documentação oficial declara que pode ser útil para manipulações gestuais, pois intercepta um evento de toque antes de ser entregue ao RecyclerView.

Raviraj
fonte
1

O RecyclerView foi criado como uma melhoria do ListView; portanto, você pode criar uma lista anexada com o controle ListView, mas usar o RecyclerView é mais fácil, pois:

  1. Reutiliza células ao rolar para cima / para baixo : isso é possível com a implementação do View Holder no adaptador ListView, mas era algo opcional, enquanto no RecycleView é a maneira padrão de gravar o adaptador.

  2. Separa a lista de seu contêiner : para que você possa colocar itens da lista facilmente em tempo de execução nos diferentes contêineres (linearLayout, gridLayout) com a configuração LayoutManager.

mRecyclerView = (RecyclerView) findViewById (R.id.my_recycler_view); mRecyclerView.setLayoutManager (novo LinearLayoutManager (este)); mRecyclerView.setLayoutManager (new GridLayoutManager (this, 2));

  1. Anima ações comuns da lista : as animações são dissociadas e delegadas ao ItemAnimator. Há mais sobre o RecyclerView, mas acho que esses pontos são os principais.

Portanto, para concluir, o RecyclerView é um controle mais flexível para lidar com "dados da lista" que segue padrões de delegação de preocupações e deixa para si apenas uma tarefa - itens de reciclagem.

farzin borujerdi
fonte
0

Se você usa o RecycleView, primeiro precisa de mais esforço para configurar. Você precisa dar mais tempo para configurar itens simples ao clicar, borda, evento de toque e outras coisas simples. Mas o produto final será perfeito.

Então a decisão é sua. Sugiro que, se você criar um aplicativo simples, como o carregamento da agenda telefônica, onde basta um simples clique do item, você poderá implementar o listview. Mas se você criar uma página inicial de mídia social com rolagem ilimitada. Várias decorações diferentes entre itens, muito controle de itens individuais do que a exibição de reciclagem.

Mahbubur Rahman Khan
fonte