ListView: o que é, listas simples em aplicativos Android

Autor: IT Sectr Publicado: 2026-02-23 Tempo de leitura: 8 min

ListView é um componente básico do Android para exibir listas verticais, disponível desde a API 1 (Android 1.0). O ListView cria uma lista de itens usando ArrayAdapter e suporta layouts de célula personalizados. Vamos entender o que é ListView, como configurá-lo e quais armadilhas este componente antigo, mas ainda usado, esconde. Na IT Sectr, encontramos ListView em projetos legados e mantemos compatibilidade com Android 4.4. Para comparação com a alternativa moderna, leia o artigo sobre RecyclerView.

Principais conclusões

  • ListView é um componente integrado do Android SDK para listas verticais, introduzido no Android 1.0.
  • ArrayAdapter é um adaptador padrão para vincular uma matriz de dados ao ListView via toString() ou layout personalizado.
  • SimpleAdapter é um adaptador para listas de dados Map, conveniente para telas simples sem ViewModel.
  • onItemClickListener é um manipulador de clique integrado que não requer implementação adicional no adaptador.
  • convertView é um mecanismo de reutilização de View no ListView que o desenvolvedor deve implementar manualmente (similar ao ViewHolder).

O que é ListView no Android?

ListView é um ViewGroup do pacote android.widget, projetado para exibir uma lista rolável de itens. O ListView implementa o padrão AdapterView: os dados são passados por meio de um adaptador (Adapter), que converte itens de dados em Views exibidas na tela. O ListView existe no Android SDK desde a primeira versão (API 1) e não requer bibliotecas adicionais.

A arquitetura do ListView é mais simples que a do RecyclerView: LayoutManager é integrado (apenas rolagem vertical), animações de alteração estão ausentes, divisores são definidos pelo atributo XML android:divider. O ListView adiciona automaticamente OverScrollView e destaque de foco, o que simplifica a prototipagem. De acordo com a Statista (2025), cerca de 15% dos aplicativos Android no top 100 da Play Store ainda contêm ListView — principalmente projetos legados com suporte mínimo.

História e relevância

O ListView foi o principal componente de lista no Android de 2008 a 2014, quando o RecyclerView foi apresentado no Google I/O 2014. Apesar de estar parcialmente obsoleto (soft-deprecated), o ListView permanece disponível em todas as versões do Android e não está marcado como @Deprecated no SDK API 35. Se seu projeto suporta Android 4.4 (API 19) e versões anteriores, o ListView é a única opção integrada, pois o RecyclerView requer AndroidX e dependências do Gradle.

Tipos de adaptadores: ArrayAdapter e SimpleAdapter

ArrayAdapter é o adaptador mais popular para ListView. Ele recebe uma List<T> e um layout para cada item. Por padrão, o ArrayAdapter chama toString() em cada objeto e exibe o texto em simple_list_item_1 (um único TextView). Para exibição personalizada, você precisa substituir getView() ou passar um layout personalizado ao construtor.

kotlin
// ListView com ArrayAdapter (texto simples)
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val countries = listOf(
        "Rússia", "EUA", "Alemanha",
        "França", "Japão", "China", "Brasil"
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val adapter = ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            countries
        )
        binding.listView.adapter = adapter

        // Manipulação de clique
        binding.listView.onItemClickListener =
            AdapterView.OnItemClickListener { _, _, position, _ ->
                Toast.makeText(this, countries[position], Toast.LENGTH_SHORT).show()
            }
    }
}

SimpleAdapter é projetado para listas de dados Map. Ele recebe uma List<Map<String, Any>> e uma matriz from/to para vincular chaves Map a IDs de widgets no layout. O SimpleAdapter é conveniente para protótipos rápidos quando uma classe de adaptador separada não é necessária. A desvantagem é a falta de tipagem segura e complexidade com lógica personalizada.

xml
<!-- Layout com ListView -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/divider"
        android:dividerHeight="1px"
        android:scrollbars="vertical" />
</LinearLayout>

Criação de um adaptador personalizado com ViewHolder

O adaptador personalizado para ListView substitui o método getView(), que o RecyclerView divide em onCreateViewHolder + onBindViewHolder. No ListView, ambas as etapas são combinadas, portanto, o desenvolvedor deve implementar independentemente o padrão ViewHolder por meio de convertView (View reutilizável) e do método setTag().

kotlin
// Modelo de dados
data class Product(
    name: String,
    price: String,
    imageResId: Int
)

// Adaptador personalizado com ViewHolder
class ProductAdapter(
    context: Context,
    private val products: List<Product>
) : ArrayAdapter<Product>(context, 0, products) {

    // ViewHolder para cache
    private class ViewHolder(view: View) {
        val nameText: TextView = view.findViewById(R.id.tvName)
        val priceText: TextView = view.findViewById(R.id.tvPrice)
        val imageView: ImageView = view.findViewById(R.id.ivProduct)
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val view = convertView ?: LayoutInflater.from(context)
            .inflate(R.layout.item_product, parent, false)
            .also { it.tag = ViewHolder(it) }

        val holder = view.tag as ViewHolder
        val product = getItem(position)

        holder.nameText.text = product.name
        holder.priceText.text = product.price
        holder.imageView.setImageResource(product.imageResId)

        return view
    }
}

Diferença principal do RecyclerView: no ListView, o método getView() é chamado toda vez que um item aparece na tela. Se convertView e ViewHolder não forem usados, cada rolagem cria um novo objeto View, causando vazamentos de memória e lentidão em listas de mais de 50 itens. ViewHolder com view.tag é uma otimização obrigatória para ListView com layouts personalizados.

Limitações do ListView: por que o Google recomenda RecyclerView

ListView tem quatro limitações arquitetônicas que o Google corrigiu no RecyclerView: (1) apenas orientação vertical — sem grades, listas horizontais ou cascatas; (2) sem notificações granulares — qualquer alteração de dados aciona um redesenho completo via notifyDataSetChanged(), causando tremulação; (3) sem animação integrada de adicionar/remover itens; (4) sem separação de responsabilidades — LayoutManager é integrado, ItemAnimator está ausente.

xml
<!-- item_product.xml — layout de item do ListView -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="12dp">

    <ImageView
        android:id="@+id/ivProduct"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:scaleType="centerCrop" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:paddingStart="12dp">

        <TextView
            android:id="@+id/tvName"
            android:textSize="16sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/tvPrice"
            android:textSize="14sp"
            android:textColor="@color/price" />
    </LinearLayout>
</LinearLayout>

Implicações práticas: em listas de até 20 itens, o ListView funciona tão rápido quanto o RecyclerView. Com mais de 100 itens, a diferença se torna perceptível: o ListView começa a perder FPS devido à falta de cálculos de diff e ao ViewHolder forçado. Para listas com atualizações frequentes (chat, feed, logs), o ListView não é adequado — use RecyclerView com Paging 3. Na IT Sectr, migramos ListView para RecyclerView sempre que trabalhamos em telas legadas com mais de 50 itens.

Configuração do ListView via atributos XML

ListView fornece um conjunto de atributos XML para configuração rápida sem código: android:divider (cor/drawable do divisor), android:dividerHeight (espessura), android:scrollbars (barras de rolagem), android:fastScrollEnabled (rolagem rápida por manipulador), android:choiceMode (modo de seleção: singleChoice, multipleChoice). O atributo android:entries permite preencher a lista a partir de uma matriz de recursos (string-array) sem adaptador.

AtributoDescriçãoExemplo de valor
android:dividerCor ou drawable do divisor@color/gray_light
android:dividerHeightEspessura do divisor em px/dp1dp
android:entriesMatriz de strings de recursos@array/countries
android:choiceModeModo de seleção de itemsingleChoice
android:fastScrollEnabledRolagem rápidatrue
android:overlapAnchorÂncora para listas popup (API 21+)true

Modo de seleção: choiceMode="singleChoice" ativa o estilo RadioButton onde o item selecionado é destacado. choiceMode="multipleChoice" — caixas de seleção para vários itens. Os dados de seleção estão disponíveis via listView.checkedItemPosition ou listView.checkedItemIds. Importante: com choiceMode, o ListView usa StateListDrawable para o fundo — defina seu próprio seletor se o azul padrão não corresponder ao design.

ListView vs RecyclerView: comparação de recursos

A escolha entre ListView e RecyclerView depende dos requisitos do projeto. RecyclerView é o padrão moderno, mas ListView pode ser justificado para telas simples com custos mínimos de manutenção de código legado. Comparação em todos os parâmetros principais:

ParâmetroListViewRecyclerView
Tamanho da bibliotecaIntegrado ao SDK (≈60 KB)AndroidX (≈300 KB com dependências)
Versão mínimaAPI 1API 14 (via AndroidX)
OrientaçãoApenas verticalVertical, horizontal, grade, escalonada
ViewHolderImplementação manualObrigatório por arquitetura
AnimaçãoApenas transições de fadeDefaultItemAnimator (add, remove, move, change)
Atualizações granularesNão (apenas notifyDataSetChanged)notifyItemInserted/Removed/Changed
Listener de cliqueonItemClickListener (integrado)Via ViewHolder (não integrado)
DesempenhoSuficiente para listas de até 50 itens60 FPS estáveis para mais de 1000 itens

Conclusão: para novos projetos, use RecyclerView. Deixe ListView apenas em código legado onde a migração é injustificadamente cara. De acordo com as diretrizes do Material Design 3 (2026), listas de qualquer complexidade devem usar RecyclerView para atender aos padrões modernos de desempenho e acessibilidade.

Perguntas frequentes

O ListView está obsoleto ou não?

ListView não está marcado como @Deprecated no Android SDK API 35, mas o Google não recomenda seu uso em novos projetos (soft-deprecated). O componente permanece funcional em todas as versões do Android. RecyclerView é a substituição oficial desde 2014. Se você está iniciando um novo projeto — escolha RecyclerView. Se está mantendo um existente — ListView continuará funcionando sem alterações.

Como adicionar header/footer ao ListView?

ListView suporta os métodos addHeaderView(View, Object, boolean) e addFooterView(View, Object, boolean). Headers e footers são adicionados à lista geral de itens, mas não participam do adaptador — eles são sempre exibidos no início e no final da lista. Importante: adicione header/footer antes de definir o adaptador (setAdapter()), caso contrário, eles não serão incluídos. Após adicionar um header, os IDs de posição dos itens são deslocados pelo número de headers.

Por que o ListView não rola dentro do ScrollView?

Tanto ListView quanto ScrollView manipulam gestos verticais, o que cria um conflito: o ScrollView externo intercepta a rolagem e o ListView não rola. Soluções: (1) não aninhe ListView dentro de ScrollView — use RecyclerView com NestedScrollingChild, (2) substitua ScrollView por NestedScrollView (API 21+), (3) use ListView com altura fixa (android:layout_height="...dp") dentro de ScrollView, mas isso quebrará a responsividade.

Como limpar o ListView e atualizar dados?

A limpeza de dados no ListView depende do tipo de adaptador. Para ArrayAdapter: adapter.clear() e adapter.addAll(newList) seguido de adapter.notifyDataSetChanged(). Para adaptador personalizado: atualize a lista de dados e chame notifyDataSetChanged(). Nota: listView.invalidateViews() apenas redesenha as Views, mas não atualiza os dados. Sempre altere os dados através do adaptador, não diretamente.

Como alterar a altura de um item do ListView?

A altura de um item do ListView é definida no layout do item. Se o layout usar layout_height="wrap_content", a altura se adapta ao conteúdo. Para uma altura fixa para todos os itens, use um adaptador personalizado que define LayoutParams em getView(): view.layoutParams.height = resources.getDimensionPixelSize(R.dimen.itemHeight). Para alturas variadas, use RecyclerView com diferentes tipos de visualização.

Resumo

  • ListView é um componente básico do Android SDK para listas verticais, disponível desde a API 1.
  • ArrayAdapter é o adaptador mais simples para uma lista de strings; para layouts personalizados, é necessário um getView() substituído.
  • ViewHolder no ListView é implementado manualmente via convertView e view.tag — um requisito obrigatório de desempenho.
  • ListView suporta choiceMode (single/multiple), header/footer, fastScroll e android:entries sem adaptador.
  • Limitações do ListView: apenas orientação vertical, sem animação, redesenho completo a qualquer alteração.
  • ListView não está marcado como obsoleto, mas o Google recomenda RecyclerView para todos os novos projetos.
  • Para listas de até 50 itens, ListView é suficiente; para algo mais complexo — use RecyclerView.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também