---
title: "Composable em Kotlin: O que É e Como Funciona | Kotlin Brasil"
url: "https://kotlin.dev.br/glossario/composable/"
markdown_url: "https://kotlin.dev.br/glossario/composable.MD"
description: "Descubra o que são funções Composable no Jetpack Compose, como criar interfaces declarativas em Kotlin para Android."
date: "2025-08-04"
author: "Karina Melo"
---

# Composable em Kotlin: O que É e Como Funciona | Kotlin Brasil

Descubra o que são funções Composable no Jetpack Compose, como criar interfaces declarativas em Kotlin para Android.


## O que é Composable em Kotlin?

Uma função **Composable** é uma função anotada com `@Composable` que descreve parte da interface do usuário no **Jetpack Compose**, o toolkit moderno de UI declarativa do Android. Em vez de montar telas com XML e manipular Views programaticamente, você escreve funções Kotlin que descrevem como a UI deve parecer para um dado estado.

O Compose e inspirado em frameworks como React e Flutter, mas aproveita todo o poder do Kotlin: type safety, extension functions, coroutines é uma sintaxe concisa que faz a construcao de interfaces parecer natural.

### Sintaxe básica

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.material3.Text

@Composable
fun Saudacao(nome: String) {
    Text(text = "Ola, $nome!")
}
```

A anotacao `@Composable` informa ao compilador do Compose que essa função descreve UI e pode ser recomposta (re-executada) quando os dados mudam. Funções Composable só podem ser chamadas dentro de outros contextos Composable.

### Composição de funções

O poder do Compose esta na composição. Você cria componentes pequenos e os combina para formar telas completas:

```kotlin
@Composable
fun CartaoDeUsuario(nome: String, email: String) {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
    ) {
        Text(
            text = nome,
            style = MaterialTheme.typography.headlineSmall
        )
        Spacer(modifier = Modifier.height(4.dp))
        Text(
            text = email,
            style = MaterialTheme.typography.bodyMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
    }
}

@Composable
fun ListaDeUsuarios(usuarios: List<Usuario>) {
    LazyColumn {
        items(usuarios) { usuario ->
            CartaoDeUsuario(
                nome = usuario.nome,
                email = usuario.email
            )
        }
    }
}
```

Cada função Composable e um bloco reutilizavel. `CartaoDeUsuario` não sabe onde sera usado, e `ListaDeUsuarios` não sabe como o cartao e renderizado internamente. Essa separação torna o código modular e testavel.

### Estado em Composables

Funções Composable são reexecutadas quando o estado muda. Para gerenciar estado local, use `remember` e `mutableStateOf`:

```kotlin
@Composable
fun Contador() {
    var contagem by remember { mutableStateOf(0) }

    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Contagem: $contagem")
        Spacer(modifier = Modifier.height(8.dp))
        Button(onClick = { contagem++ }) {
            Text("Incrementar")
        }
    }
}
```

Quando `contagem` muda, o Compose recompoe apenas as partes da UI que dependem desse valor. Isso e feito de forma inteligente pelo runtime do Compose, que rastreia quais Composables leem quais estados.

### Recomposicao

Recomposicao e o processo pelo qual o Compose reexecuta funções Composable quando os dados de entrada mudam. E importante entender que:

- A recomposicao pode acontecer a **qualquer momento** e em **qualquer ordem**.
- Funções Composable devem ser **idempotentes**: chamar com os mesmos parametros deve produzir o mesmo resultado.
- Funções Composable não devem ter **efeitos colaterais** não controlados.

```kotlin
// Correto: sem efeitos colaterais
@Composable
fun ExibirNome(nome: String) {
    Text(text = nome)
}

// Incorreto: efeito colateral na recomposicao
@Composable
fun ExibirNomeComLog(nome: String) {
    println("Recompondo...") // Pode ser chamado muitas vezes!
    Text(text = nome)
}
```

Para efeitos colaterais controlados, use APIs como `LaunchedEffect`, `SideEffect` e `DisposableEffect`.

### Efeitos colaterais controlados

```kotlin
@Composable
fun TelaDeDetalhes(userId: String) {
    var usuario by remember { mutableStateOf<Usuario?>(null) }

    LaunchedEffect(userId) {
        // Executa quando userId muda
        usuario = repositorio.buscarUsuario(userId)
    }

    usuario?.let { u ->
        Column {
            Text(text = u.nome)
            Text(text = u.email)
        }
    }
}
```

`LaunchedEffect` lanca uma coroutine que e cancelada e reiniciada quando a chave (`userId`) muda. Isso garante que efeitos colaterais sejam gerenciados corretamente no ciclo de vida do Composable.

### Modifiers

Modifiers são o mecanismo do Compose para decorar e configurar componentes:

```kotlin
@Composable
fun CartaoEstilizado() {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
            .clickable { /* acao */ }
    ) {
        Text(
            text = "Conteudo do cartao",
            modifier = Modifier.padding(24.dp)
        )
    }
}
```

A ordem dos modifiers importa: `padding` antes de `clickable` produz resultado diferente de `clickable` antes de `padding`.

### Quando usar Composables

Composables são usados em qualquer projeto Android que adote Jetpack Compose:

- **Telas de aplicativos**: construir layouts completos de forma declarativa.
- **Componentes reutilizaveis**: criar uma biblioteca de componentes de UI consistentes.
- **Previews**: usar `@Preview` para visualizar componentes no Android Studio sem rodar o app.
- **Testes de UI**: Composables são facilmente testáveis com a biblioteca de testes do Compose.
- **Compose Multiplatform**: o mesmo conceito funciona em desktop, web e iOS com Kotlin Multiplatform.

### Casos de Uso no Mundo Real

1. **Design systems corporativos**: empresas criam bibliotecas de Composables reutilizaveis (botoes, campos de texto, cartoes, modais) que encapsulam regras de design e acessibilidade. Equipes de produto consomem esses componentes para garantir consistencia visual em dezenas de telas sem duplicar código de estilizacao.

2. **Telas de formularios dinâmicos**: aplicações que renderizam formularios baseados em configuracoes do servidor (como cadastros, pesquisas ou checklists) usam Composables parametrizados que recebem a definicao dos campos e geram a interface automaticamente. Cada tipo de campo (texto, selecao, data) e um Composable independente composto pela tela pai.

3. **Dashboards com gráficos e metricas**: aplicações de analytics e monitoramento constroem paineis interativos usando Composables que reagem a mudancas de estado em tempo real. Graficos, indicadores e tabelas sao componentes Compose que se recompoem automaticamente quando os dados sao atualizados via Flow ou StateFlow do ViewModel.

4. **aplicações multiplataforma com Compose Multiplatform**: projetos que compartilham a mesma base de código Kotlin entre Android, desktop (Windows, macOS, Linux) e iOS usam Composables como a camada de UI unificada. Um mesmo componente de lista ou navegação funciona em todas as plataformas com adaptacoes minimas.

### Boas Praticas

- Aplique state hoisting por padrão: Composables devem receber o estado como parametro e emitir eventos via callbacks. Isso torna o componente stateless, reutilizavel e facilmente testavel com a biblioteca de testes do Compose.
- Mantenha Composables pequenos e focados em uma única responsabilidade. Um Composable que faz muita coisa (busca dados, processa lógica e renderiza UI) e difícil de testar e reutilizar. Delegue lógica de negócio ao ViewModel.
- Use `@Preview` com múltiplas configuracoes (temas claro e escuro, diferentes tamanhos de tela, dados de exemplo variados) para validar a aparencia do componente sem precisar compilar e executar o aplicativo inteiro.
- Evite efeitos colaterais diretos dentro de Composables. Use `LaunchedEffect` para coroutines, `SideEffect` para código sincrono que precisa executar apos a composicao e `DisposableEffect` para recursos que precisam de limpeza.
- Preste atencao na ordem dos Modifiers: cada modifier e aplicado em sequência e afeta o resultado visual de forma cumulativa. Por exemplo, `padding` antes de `background` adiciona espaco dentro da area colorida, enquanto a ordem inversa adiciona espaco fora.

### Perguntas Frequentes

**P: Qual a diferenca entre `remember` e `rememberSaveable` no Compose?**
R: `remember` preserva o estado entre recomposicoes, mas o valor se perde em mudancas de configuração (como rotação de tela) ou quando o processo e destruído. `rememberSaveable` salva o estado automaticamente no `SavedStateHandle`, sobrevivendo a mudancas de configuração e até a morte do processo, desde que o valor seja serializavel.

**P: Composables podem ser usados fora do Android?**
R: Sim. Com o Compose Multiplatform da JetBrains, você pode usar Composables em aplicações desktop (JVM), web (via Kotlin/Wasm) e iOS. A API de composicao e recomposicao e a mesma; o que muda sao os componentes de plataforma subjacentes que renderizam os elementos visuais.

**P: Como testar Composables de forma automatizada?**
R: Use a biblioteca `compose-ui-test` que fornece a `ComposeTestRule`. Com ela você pode renderizar Composables isolados, interagir com elementos via `onNodeWithText` e `performClick`, e verificar estados com assertivas como `assertIsDisplayed`. Testes de Composable executam no JVM sem precisar de um emulador.

**P: Por que meu Composable esta recompondo mais vezes do que o esperado?**
R: Recomposicoes excessivas geralmente acontecem quando o estado e lido em um escopo mais amplo do que necessário, quando lambdas sao recriadas a cada recomposicao (use `remember` para estabiliza-las), ou quando objetos de dados não implementam `equals` corretamente. Use o Layout Inspector do Android Studio para identificar quais Composables estao recompondo e com que frequência.

### Erros comuns

1. **Colocar lógica de negócio dentro do Composable**: Composables devem apenas descrever UI. Logica de negócio pertence ao ViewModel ou a camadas inferiores.

2. **Esquecer `remember`**: sem `remember`, o estado e recriado a cada recomposicao, perdendo o valor anterior.

```kotlin
// Errado: contagem volta a 0 a cada recomposicao
@Composable
fun ContadorQuebrado() {
    var contagem = mutableStateOf(0) // Falta remember!
    // ...
}
```

3. **Efeitos colaterais descontrolados**: fazer chamadas de rede, acessar banco de dados ou modificar estado global diretamente dentro de um Composable sem usar `LaunchedEffect` ou similar.

4. **Nao elevar o estado (state hoisting)**: manter estado em componentes filhos quando ele deveria ser controlado pelo pai. Isso dificulta reutilização e testes.

5. **Ignorar a ordem dos Modifiers**: como modifiers são aplicados em cadeia, a ordem afeta o resultado visual. Testar e visualizar com `@Preview` ajuda a pegar esses problemas cedo.

### State hoisting

Um padrão fundamental em Compose e elevar o estado para o componente pai:

```kotlin
// Componente stateless (sem estado proprio)
@Composable
fun CampoDeTexto(
    valor: String,
    onValorMudou: (String) -> Unit
) {
    TextField(
        value = valor,
        onValueChange = onValorMudou
    )
}

// Componente pai controla o estado
@Composable
fun Formulario() {
    var nome by remember { mutableStateOf("") }
    CampoDeTexto(
        valor = nome,
        onValorMudou = { nome = it }
    )
}
```

Isso torna `CampoDeTexto` reutilizavel e testavel, pois ele não gerencia seu próprio estado.

### Termos relacionados

- **State**: o mecanismo de estado reativo que aciona recomposicoes quando valores mudam.
- **Modifier**: objeto que configura aparencia e comportamento de componentes Compose.
- **ViewModel**: gerencia estado e lógica de negócio fora da camada de UI.
- **LaunchedEffect**: API para executar efeitos colaterais controlados dentro de Composables.
- **Recomposicao**: processo de reexecucao de funções Composable quando seus inputs mudam.
- **remember**: função que preserva estado entre recomposicoes.

Composables representam uma mudanca de paradigma na construcao de interfaces em Kotlin. Ao tratar a UI como função do estado, o Compose elimina toda uma classe de bugs relacionados a sincronizacao entre dados e interface, tornando o desenvolvimento mais previsivel e produtivo.
