Estou tentando determinar a melhor maneira de ter um único ListView que contém layouts diferentes para cada linha. Eu sei como criar uma linha personalizada + adaptador de matriz personalizado para oferecer suporte a uma linha personalizada para a exibição de lista inteira, mas como implementar vários estilos de linha diferentes no ListView?
android
listview
listviewitem
w.donahue
fonte
fonte
Respostas:
Como você sabe quantos tipos de layout você teria - é possível usar esses métodos.
getViewTypeCount()
- esse método retorna informações quantos tipos de linhas você tem na sua listagetItemViewType(int position)
- retorna informações que tipo de layout você deve usar com base na posiçãoEntão você aumenta o layout apenas se for nulo e determina o tipo usando
getItemViewType
.Veja este tutorial para obter mais informações.
Para obter algumas otimizações na estrutura que você descreveu no comentário, sugiro:
ViewHolder
. Isso aumentaria a velocidade, porque você não precisará chamarfindViewById()
todas as vezes nogetView
método. Veja List14 nas demos da API .Espero que isso ajude você. Se você pudesse fornecer algum stub XML com sua estrutura de dados e informações sobre como exatamente deseja mapeá-lo em linha, eu seria capaz de fornecer conselhos mais precisos. Por pixel.
fonte
Você já conhece o básico. Você só precisa obter seu adaptador personalizado para retornar um layout / visualização diferente com base nas informações de linha / cursor que estão sendo fornecidas.
A
ListView
pode suportar vários estilos de linha porque deriva do AdapterView :Se você olhar para o adaptador , verá métodos que consideram o uso de visualizações específicas de linha:
Os dois últimos métodos fornecem a posição para que você possa usá-lo para determinar o tipo de exibição que você deve usar para essa linha .
Obviamente, você geralmente não usa o AdapterView e o Adapter diretamente, mas usa ou deriva de uma de suas subclasses. As subclasses do Adapter podem adicionar funcionalidades adicionais que alteram como obter layouts personalizados para diferentes linhas. Como a visualização usada para uma determinada linha é direcionada pelo adaptador, o truque é fazer com que o adaptador retorne a visualização desejada para uma determinada linha. Como fazer isso difere dependendo do adaptador específico.
Por exemplo, para usar ArrayAdapter ,
getView()
para aumentar, preencher e retornar a visualização desejada para a posição especificada. OgetView()
método inclui uma exibição de reutilização de oportunidade por meio doconvertView
parâmetroMas, para usar derivados do CursorAdapter ,
newView()
para aumentar, preencher e retornar a visualização desejada para o estado atual do cursor (ou seja, a "linha" atual) [você também precisa substituirbindView
para que o widget possa reutilizar visualizações]No entanto, para usar o SimpleCursorAdapter ,
SimpleCursorAdapter.ViewBinder
com umsetViewValue()
método para aumentar, preencher e retornar a visualização desejada para uma determinada linha (estado atual do cursor) e a "coluna" de dados. O método pode definir apenas as visualizações "especiais" e adiar para o comportamento padrão do SimpleCursorAdapter para as ligações "normais".Procure os exemplos / tutoriais específicos para o tipo de adaptador que você acaba usando.
fonte
BaseAdapter
. Derivar o BaseAdapter seria o mais "flexível", mas seria o pior na reutilização e maturidade do código, pois ele não tira proveito do conhecimento e maturidade já colocados nos outros adaptadores.BaseAdapter
existe para contextos não padrão em que os outros adaptadores não se encaixam.CursorAdapter
eSimpleCursorAdapter
.ArrayAdapter
, não importa o que o layout que você dá o construtor, contanto quegetView()
infla e retorna o tipo certo de disposiçãogetViewTypeCount()
é acionado apenas uma vez toda vez que você ligaListView.setAdapter()
, não para todasAdapter.notifyDataSetChanged()
.Dê uma olhada no código abaixo.
Primeiro, criamos layouts personalizados. Nesse caso, quatro tipos.
even.xml
odd.xml
white.xml
black.xml
Em seguida, criamos o item de exibição de lista. No nosso caso, com uma string e um tipo.
Depois disso, criamos um suporte de visualização. É altamente recomendável porque o sistema operacional Android mantém a referência de layout para reutilizar seu item quando ele desaparece e aparece na tela. Se você não usar essa abordagem, sempre que o item aparecer na tela do sistema operacional Android criará um novo e fará com que o aplicativo perca memória.
Por fim, criamos nosso adaptador personalizado substituindo getViewTypeCount () e getItemViewType (int position).
E nossa atividade é mais ou menos assim:
agora crie uma listview dentro do mainactivity.xml como este
fonte
No seu adaptador de matriz personalizado, você substitui o método getView (), como você provavelmente já conhece. Tudo o que você precisa fazer é usar uma instrução switch ou if para retornar uma determinada visualização personalizada, dependendo do argumento de posição passado ao método getView. O Android é inteligente, pois fornecerá apenas um convertView do tipo apropriado para sua posição / linha; você não precisa verificar se é do tipo correto. Você pode ajudar o Android substituindo os métodos getItemViewType () e getViewTypeCount () adequadamente.
fonte
Se precisarmos mostrar um tipo diferente de exibição na exibição em lista, é bom usar getViewTypeCount () e getItemViewType () no adaptador em vez de alternar uma exibição VIEW.GONE e VIEW.VISIBLE pode ser uma tarefa muito cara dentro de getView () que afetam a rolagem da lista.
Por favor, verifique este para o uso de getViewTypeCount () e getItemViewType () no adaptador.
Link: o-uso-de-getviewtypecount
fonte
O ListView foi projetado para casos de uso simples, como a mesma exibição estática de todos os itens de linha.
Como você precisa criar ViewHolders e fazer uso significativo de
getItemViewType()
, e mostrar dinamicamente diferentes xmls de layout de itens de linha, tente fazer isso usando o RecyclerView , disponível na API Android 22. Ele oferece melhor suporte e estrutura para vários tipos de exibição.Confira este tutorial sobre como usar o RecyclerView para fazer o que você está procurando.
fonte