@Composable: o que é, anotação Compose e âmbito de aplicação

Autor: IT Sectr Publicado: 2026-06-27 Tempo de leitura: 8 min

A anotação @Composable é um elemento fundamental do Jetpack Compose que transforma uma função Kotlin comum em um bloco de construção declarativo da interface do usuário. Sem esta anotação, é impossível criar qualquer tela no desenvolvimento moderno do Android. Segundo Google Android Developers, 2026, mais de 80% dos novos projetos em Kotlin usam Compose para construir UI, e @Composable é a anotação mais usada no ecossistema.

Principais Pontos

  • @Composable — uma anotação Kotlin que permite a uma função descrever UI declarativamente
  • Funções Composable só podem chamar outras funções Composable, respeitando o contexto de composição
  • Reinicialização das funções Composable ocorre quando os parâmetros de entrada ou estado mudam
  • Ordem de chamada das funções Composable não é garantida — Compose otimiza a reconstrução da UI
  • Nomeação das funções Composable segue a convenção PascalCase, como qualquer componente no Compose

O que é @Composable no Jetpack Compose

@Composable é uma anotação da linguagem Kotlin que marca uma função como destinada a descrever a interface do usuário no framework Jetpack Compose. Quando o compilador Kotlin encontra esta anotação, ele gera código adicional que permite à função trabalhar no contexto de composição — o sistema de gerenciamento de árvore de UI.

A anotação @Composable foi apresentada pelo Google em 2021 junto com a primeira versão estável do Jetpack Compose 1.0. Antes de seu aparecimento, o desenvolvimento de interfaces no Android era feito exclusivamente através de marcação XML e do sistema View. O @Composable mudou radicalmente a abordagem: em vez de descrever a UI em um arquivo de marcação separado, o desenvolvedor escreve a interface diretamente em Kotlin.

A principal diferença entre @Composable e funções Kotlin comuns é a capacidade de ler e reagir a mudanças de estado. Quando uma variável que uma função Composable lê muda seu valor, o sistema agenda automaticamente uma reinicialização (recomposição) dessa função. Isso libera o desenvolvedor de atualizar manualmente a UI através de findViewById e setText.

A mecânica interna do @Composable se baseia no conceito de slot — uma área de memória especial alocada para cada função dentro da composição. Este slot armazena os valores passados para a função, bem como as informações de serviço necessárias para comparação em chamadas subsequentes.

Como declarar uma função Composable

Para declarar uma função Composable, basta adicionar a anotação @Composable antes da palavra-chave fun. A função deve estar em um pacote que importe a anotação de androidx.compose.runtime. Recomenda-se escrever o nome da função com letra maiúscula — esta é uma convenção amplamente aceita na comunidade Compose que distingue visualmente os componentes de UI das funções comuns.

kotlin
import androidx.compose.runtime.Composable

@Composable
fun Greeting(name: String) {
    var count by remember { mutableStateOf(0) }
    Column {
        Text("Olá, $name!")
        Button(onClick = { count++ }) {
            Text("Clicado $count vezes")
        }
    }
}

Os parâmetros de uma função Composable podem ser qualquer coisa — tipos primitivos, strings, lambdas e até outras funções Composable passadas através da Slot API. Recomenda-se tornar os parâmetros imutáveis (val) para evitar efeitos colaterais durante a recomposição. Todos os dados mutáveis devem ser gerenciados através dos mecanismos de estado do Compose.

Funções Composable não podem retornar valores arbitrários como funções regulares — sua única tarefa é construir ou atualizar um fragmento da árvore de UI. No entanto, existem padrões especiais como State Hoisting, onde uma função Compose aceita estado e callbacks através de parâmetros, permanecendo pura e reutilizável.

Regras das funções Composable em Kotlin

O sistema Compose impõe várias restrições estritas sobre como as funções Composable devem parecer e se comportar. A primeira regra: uma função Composable só pode chamar outras funções Composable ou funções regulares que não tenham efeitos colaterais. Isso garante a previsibilidade da composição e o funcionamento correto das otimizações do Compose.

A segunda regra diz respeito à ordem de execução. O Compose tem o direito de chamar funções Composable em qualquer ordem, portanto o código no corpo dessa função não deve depender da sequência de chamada das funções vizinhas. Cada função Composable deve ser autossuficiente ao nível de sua posição na árvore de UI.

A terceira regra — proibição de efeitos colaterais dentro do corpo de uma função Composable. Operações como escrever no banco de dados, enviar requisições de rede ou modificar variáveis externas devem ser realizadas apenas dentro de efeitos especiais: LaunchedEffect, DisposableEffect ou SideEffect. Violar esta regra leva a comportamento imprevisível durante as recomposições.

A quarta regra: funções Composable devem ser idempotentes. Chamá-las novamente com os mesmos argumentos deve produzir a mesma UI. Este requisito é necessário para o correto funcionamento da otimização skipping, onde o Compose pula a redesenho de funções cujos dados de entrada não mudaram.

kotlin
// Correto: função Composable pura sem efeitos colaterais
@Composable
fun UserCard(user: User, onClick: () -> Unit) {
    Card(modifier = Modifier.clickable { onClick() }) {
        Text(text = user.name)
    }
}

// Errado: efeito colateral dentro do corpo
@Composable
fun WrongCard(userId: String) {
    // val result = viewModel.loadUser(userId)  // NÃO PERMITIDO
    Text("Carregando...")
}

Exemplos de uso do @Composable

Vamos ver um exemplo prático de criação de uma tela de perfil usando a anotação @Composable. Aqui demonstramos a combinação de múltiplas funções Composable, trabalho com estado e modificadores — elementos-chave de qualquer layout Compose.

kotlin
@Composable
fun ProfileScreen(userId: String) {
    var isFollowed by remember { mutableStateOf(false) }

    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        ProfileHeader(userId = userId)
        Spacer(modifier = Modifier.height(16.dp))
        StatsRow(posts = 42, followers = 1280)
        Spacer(modifier = Modifier.height(24.dp))
        FollowButton(
            isFollowed = isFollowed,
            onToggle = { isFollowed = !isFollowed }
        )
    }
}

@Composable
fun ProfileHeader(userId: String) {
    Row(verticalAlignment = Alignment.CenterVertically) {
        AsyncImage(model = "https://example.com/avatars/$userId",
            contentDescription = "User avatar")
        Spacer(modifier = Modifier.width(12.dp))
        Text(text = "Usuário #$userId", style = MaterialTheme.typography.headlineMedium)
    }
}

@Composable
fun StatsRow(posts: Int, followers: Int) {
    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
        StatItem("Posts", posts)
        StatItem("Followers", followers)
    }
}

@Composable
fun StatItem(label: String, value: Int) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "$value", style = MaterialTheme.typography.headlineSmall)
        Text(text = label, style = MaterialTheme.typography.bodySmall)
    }
}

No exemplo, cada função Composable é responsável por sua parte da tela: ProfileScreen gerencia o estado geral e a composição das funções filhas, ProfileHeader exibe o avatar e o nome, e StatsRow mostra um bloco de estatísticas. Esta abordagem segue o princípio de responsabilidade única e simplifica a reutilização de componentes.

Tipos de funções Composable e sua finalidade

No Jetpack Compose, existem três tipos principais de funções Composable. O primeiro tipo — contêineres (Row, Column, Box, LazyColumn) — determina a disposição dos elementos filhos. O segundo tipo — elementos de exibição (Text, Image, Icon, Button) — renderizam componentes de UI específicos. O terceiro tipo — funções Composable personalizadas — combinam componentes integrados em blocos reutilizáveis.

Os contêineres diferem dos elementos regulares por aceitarem uma lambda content — o último parâmetro do tipo @Composable () -> Unit. Este mecanismo permite construir árvores de UI aninhadas: cada contêiner gera uma composição filha com seu próprio contexto e área de memória.

Funções Composable personalizadas se dividem em dois subtipos: inteligentes (smart) e simples (dumb). Funções inteligentes gerenciam estado e lógica — contêm chamadas a remember, LaunchedEffect e outras APIs do Compose. Funções simples recebem todos os dados através de parâmetros e apenas os exibem. A separação em componentes inteligentes e simples melhora a testabilidade e a reutilização de código.

TipoExemploFinalidade
ContêinerColumn, Row, BoxGerenciamento da disposição de elementos filhos
ElementoText, Image, ButtonExibição de conteúdo e tratamento de entrada
PersonalizadoProfileCard, UserListCombinação de componentes padrão

@Composable e reutilização de componentes

A principal vantagem da anotação @Composable é a capacidade de criar componentes de UI reutilizáveis sem herança e hierarquias complexas de classes. Ao contrário do sistema View, onde cada elemento personalizado exigia a criação de uma classe Java com construtores, um componente Composable é simplesmente uma função Kotlin com parâmetros.

Para garantir a reutilização, utiliza-se o padrão Slot API, onde uma função Composable aceita lambdas content para diferentes áreas de seu layout. Por exemplo, um componente Card pode aceitar conteúdo separado para o cabeçalho, corpo e rodapé, tornando-o universal para qualquer tela do aplicativo.

Os modificadores (Modifier) desempenham um papel fundamental na reutilização: permitem configurar paddings, tamanhos, cliques e animações sem alterar o componente em si. Recomenda-se sempre passar Modifier como parâmetro de uma função Composable com valor padrão: Modifier = Modifier — esta é uma prática padrão adotada nas bibliotecas oficiais do Google.

kotlin
@Composable
fun SectionCard(
    modifier: Modifier = Modifier,
    title: String,
    content: @Composable () -> Unit
) {
    Card(modifier = modifier) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(text = title, style = MaterialTheme.typography.titleMedium)
            Spacer(modifier = Modifier.height(8.dp))
            content()
        }
    }
}

Graças à Slot API, o componente SectionCard pode ser usado em diferentes telas com diferentes conteúdos — formulários, listas, blocos de texto. A combinação de modificadores e Slot API torna os componentes Compose extremamente flexíveis sem perder a segurança de tipos que o Kotlin proporciona.

Perguntas Frequentes

Como @Composable difere de uma função Kotlin comum?

Uma função @Composable é executada no contexto de composição e pode ler estado, reiniciando automaticamente quando ele muda. Funções Kotlin comuns não têm acesso aos mecanismos de rastreamento de estado e não participam da construção da árvore de UI.

Pode-se chamar uma função Composable de uma função normal?

Não, funções Composable só podem ser chamadas de outras funções Composable, pois é necessário um contexto de composição especial. Para integrar código Compose com Kotlin normal, usa-se o método setContent { } na Activity ou ComposeView no sistema View.

Por que as funções Composable são escritas com letra maiúscula?

Esta é uma convenção de nomenclatura adotada na comunidade Compose. A letra maiúscula distingue visualmente os componentes de UI das funções comuns, seguindo as regras de nomenclatura de classes. Não é um requisito do compilador, mas uma prática recomendada na documentação do Google.

Quantas funções Composable podem estar em uma tela?

Não há limites na quantidade. Na prática, uma tela grande pode conter 50–100 funções Composable, incluindo componentes integrados (Text, Button) e personalizados. O Compose otimiza a árvore de funções e executa apenas aquelas cujos dados de entrada mudaram.

Uma função Composable pode retornar um valor?

Normalmente funções Composable retornam Unit, já que sua tarefa é construir a UI. No entanto, existem funções especializadas como remember e derivedStateOf que são marcadas com @Composable e retornam valores. Esta é uma exceção, não a regra.

Resumo

  • @Composable — anotação para descrição declarativa de UI no Jetpack Compose
  • Funções Composable são chamadas apenas dentro de outras funções Composable em contexto especial
  • Idempotência — cada execução repetida com os mesmos argumentos produz a mesma UI
  • Efeitos colaterais proibidos no corpo da função — apenas via LaunchedEffect e SideEffect
  • Slot API e Modifier garantem reutilização de componentes sem herança
  • Funções contêiner (Row, Column, LazyColumn) aceitam lambdas content para elementos aninhados
  • Recomendação: passar Modifier como parâmetro de cada função Composable personalizada com valor padrão

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