Listas No Android
As listas são os tipos mais comuns de visualização de dados no Android. Basicamente quase tudo usa listas: Contatos do Telefone, emails, ligações perdidas, etc..
O Android possui muitas otimizações para os diversos tipos de Listas existentes, mas por vezes ainda nos sentimos penalizados pelo desempenho, sobretudo quando usamos scroll em listas muitas longas.
Isso é especialmente verdade em aparelhos menos favorecidos. Nós desenvolvedores geralmente temos acesso aos modelos Top de Linha, e nos esquecemos que a maioria das pessoas não possui aparelhos tão poderosos.
O problema de Desempenho
O problema de desempenho se deve a forma como as listas são renderizadas no android. Para trabalhar com listas no Android usamos um Adapter que itera sobre a lista de chama o método getView() para cada item.
Na primeira vez que um item é carregado a nossa convertView é nula então o layout do item da lista é inflado, e então buscamos nosso elementos na View do método findViewById().
Na segunda vez que um item é carregado, nossa convertView não é mais nula, então não precisamos inflá-la, porém chamamos mais uma vez o findViewById para buscar as referências aos nossos elementos da View.
Para cada item da nossa listas isso se repete, e chamamos o findViewById repetidas vezes.
O método findViewById é um método muito custoso, ele recorre todos os elementos da nossa View e verifica o seu ID, para só então retornar uma instância daquela objeto. Quando menos vezes isso for feito, melhor.
O Padrão ViewHolder
O padrão viewHolder é um padrão de projetos que permite que cada elemento visual dos itens da nossa lista sejam acessados sem que haja necessidade de ficar buscando-os na view repetidas vezes. Isso diminui em muito a carga de processamento e torna a rolagem da lista mais fluída, mesmo em aparelhos menos poderosos.
Agora usando a viewHolder, nossa pesquisa por elementos fica cacheada e não precisamos mais buscar suas instâncias com findViewById. Vejamos como ficou o novo fluxo.
A primeira vez que um item é carregado a nossa convertView é nula então o layout do item da lista é inflado, e então buscamos nosso elementos na View do método findViewById().
Na segunda vez que um item é carregado, nossa convertView não é mais nula, ótimo. E como possuímos uma instância da nossa viewHolder, não precisamos buscar os elementos na View, basta usar as referências que já possuímos.
Nas vezes subsequentes, nossa convertView nunca será nula, e não precisaremos nunca mais buscar instâncias do elementos com findViewById.
Código de Exemplo
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderItem viewHolder;
if(convertView == null){
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(mLayoutResourceId, parent, false);
viewHolder = new ViewHolderItem();
viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textViewItem);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolderItem) convertView.getTag();
}
String item = mData[position];
if(item != null) {
viewHolder.textViewItem.setText(item);
convertView.setTag(viewHolder);
}
return convertView;
}
Você pode baixar o código completo aqui no meu GitHub.
Até a próxima.
Kommentarer