Quando vamos fazer um aplicativo Android, inúmeras vezes será necessário utilizar uma lista, o Alex mostrou para gente como criar uma lista e personaliza-la usando .
Autor(a)
matheus.brandino
Inscreva-se em nossa Newsletter
Fique por dentro de conteúdos, insights e oportunidades do universo tech. Receba novidades e lançamentos direto no seu e-mail.
ListView
Depois que fazemos todo esse procedimento vemos que a listagem às vezes engasga quando estamos passando os seus itens, vamos entender porque isso acontece. Vamos analisar esse Adapter :
Bom, nada de novo até agora, mas nesse momento estamos com um pequeno problema, quando nossa lista está com muitos itens ela trava, por quê ?
Entendendo o processo de criação entre a ListView e o Adapter
O ListView quando é criado, pergunta ao Adapter qual é a quantidade de itens que ele terá, e recebe a resposta atráves do método getCount().
Quando recebe a quantidade ele começa a se preparar para exibir os itens, vendo a quantidade que caberá na tela, vamos imaginar que sejam apenas 5 itens qua possam ser exibidos, nisso o Android vai inflar esses 5 itens e vai devolver para o ListView através do método getView(), além disso o Android acaba inflando mais duas views, para reaproveitarmos.
Está view que é criada para reaproveitamento é a view que recebemos como parâmetro no método getView(), chamamos ela de convertView :
Contudo se olharmos nosso código em momento algum estamos utilizando a convertView, para cada view que o ListView pede estamos inflando uma nova, por esse motivo a lista começa a engasgar, devido a falta de memória.
Refatorando o adapter para reaproveitar a view
Vamos então refatorar nosso código para deixar nossa ListView com uma boa performance. Para isso precisamos saber se já temos uma view pronta para ser reaproveitada, caso tenhamos nós iremos utiliza-la, caso contrário teremos que inflar uma nova.
Agora estamos reaproveitando a view da forma que queríamos, entretanto ainda podemos melhorar bastante a questão de performance.
Como estamos reaproveitando, nós já conhecemos todas as view que aquele item possui, mas ainda assim estamos fazendo findViewById() para cada view.
O findViewById() percorre o xml em busca da view, perguntando para cada view se ela possui aquele id, indo da view principal descendo sobre seus "filhos" da esquerda para a direita, como se fosse uma árvore genealógica.
Isso num layout mais complexo levaria um certo tempo para encontrar cada view certinha e popula-la, por isso precisamos dar um jeito de fazermos a busca apenas quando criamos o item e quando reaproveitarmos o item criado, também aproveitar as buscas.
Dessa forma resolvemos o problema! Pena que o compilador está reclamando, pois quando formos reaproveitar uma view não teremos referência para os TextView, e agora?
Implementando o ViewHolder
Bom, para resolvermos esse problema existe um design pattern chamado ViewHolder que irá segurar as informações da view.
Para utilizarmos esse pattern iremos criar uma classe que precisará da view que ela pegará as informações.
publicclassViewHolder {
final TextView nome; final TextView email;
publicViewHolder(View view){
nome = (TextView) view.findViewById(R.id.item_nome);
email = (TextView) view.findViewById(R.id.item_email);
}
}
Legal, classe criada, está faltando apenas a usarmos. Bora fazer isso !
Poxa, parece tudo certo, entretanto ainda estamos sendo barrados pelo compilador. O mesmo erro que estávamos lendo antes, quando formos reaproveitar a view o ViewHolder não será criado, portanto não terá referência para ser usado.
Para resolver isso, precisamos deixar o ViewHolder "pendurado" na view que ele pertence, dessa forma, quando formos reaproveitar a view, conseguiremos o recuperar.
Embora tenhamos implementado a ListView considerando todos os detalhes que vimos neste post, repare que tivemos que ter o conhecimento do ViewHolder para implementá-lo. Em outras palavras, se não o conhecêssemos, ainda teríamos o problema de performance conforme a lista fosse crescendo...
Pensando justamente nesse e outros detalhes, a Google disponibilizou uma API mais inteligente para a criação de listas que já nos obriga a realizar todas as implementações que vimos no Adapter e na ListView, e também, a implementação do ViewHolder!
Essa é a API RecyclerView que é explicada com mais detalhes nesse post que escrevi! Recomendo fortemente a leitura, pois é a forma mais adotada pelos desenvolvedores Android para criação de lista nas Apps.
Resumo
Como vimos, para termos um ListView com boa performance, precisamos reutilizar as views que o Android cria a mais para gente, só para lembrarmos o nome que damos para essa view é convertView.
Além disso para melhorar de vez a performance, podemos evitar que ele faça findViewByIds desnecessários, utilizamos o padrão ViewHolder que irá cuidar de fazer isso para nós e associamos ele a view cujo ele pertence, desta forma otimizamos bastante o funcionamento da lista, agora nada de ve-lá engasgar! :D