Composable Function: cos'è, sintassi della funzione e regole

Autore: IT Sectr Pubblicato: 2026-06-27 Tempo di lettura: 8 min

Composable Function è un'unità fondamentale dell'interfaccia utente in Jetpack Compose che definisce come una parte dello schermo dovrebbe apparire e comportarsi. Ogni funzione è contrassegnata dall'annotazione @Composable ed eseguita in un contesto speciale che consente a Compose di tracciare le dipendenze e ricostruire automaticamente l'UI quando i dati cambiano. Secondo Google Android Developers, 2026, la corretta costruzione delle funzioni Composable influisce direttamente sulle prestazioni dell'applicazione e sull'efficienza della ricomposizione.

Punti chiave

  • Composable Function — una funzione Kotlin con annotazione @Composable che costruisce un albero UI
  • I parametri devono essere immutabili, i dati mutabili vanno attraverso state
  • La chiamata è possibile solo dal contesto di un'altra funzione Composable
  • L'ordine di esecuzione non è garantito — ogni funzione deve essere indipendente
  • Modifier è raccomandato come parametro per la personalizzazione

Cos'è una Composable Function in Jetpack Compose

Una Composable Function è una funzione nel linguaggio Kotlin, contrassegnata dall'annotazione @Composable, che descrive una parte dell'interfaccia utente in modo dichiarativo. Invece di creare e configurare oggetti View tramite codice Java o markup XML, lo sviluppatore scrive semplicemente come dovrebbe apparire l'UI per ogni stato dei dati.

La differenza principale tra una funzione Composable e il sistema View tradizionale di Android risiede nel modello di aggiornamento. Nell'approccio classico, lo sviluppatore chiamava manualmente findViewById, modificava il testo tramite setText e gestiva la visibilità tramite setVisibility. Composable Function ti libera da questa routine: quando i dati cambiano, il sistema stesso determina quali funzioni devono essere ricomposte ed esegue solo quelle.

Il compilatore Kotlin, elaborando l'annotazione @Composable, genera codice aggiuntivo che integra la funzione nel meccanismo di composizione. Questo codice include la lettura e scrittura in slot — celle di memoria speciali che memorizzano lo stato e i parametri di ciascuna funzione Composable nell'albero UI corrente. Grazie a questa integrazione, Compose sa quali funzioni dipendono da quali dati.

Sintassi di dichiarazione di una funzione Composable

La sintassi di una funzione Composable è estremamente concisa: basta aggiungere @Composable prima della parola chiave fun. La funzione può accettare qualsiasi parametro, includere altre chiamate Composable nel suo corpo e utilizzare costrutti Kotlin — condizioni, cicli, espressioni when — per il rendering condizionale dell'UI.

kotlin
@Composable
fun ProductItem(
    product: Product,
    modifier: Modifier = Modifier,
    onAddToCart: () -> Unit
) {
    Card(modifier = modifier.padding(8.dp)) {
        Row(modifier = Modifier.fillMaxWidth().padding(12.dp),
            verticalAlignment = Alignment.CenterVertically) {
            Column(modifier = Modifier.weight(1f)) {
                Text(text = product.name, style = MaterialTheme.typography.titleMedium)
                Text(text = "${product.price}", color = MaterialTheme.colorScheme.primary)
            }
            Button(onClick = onAddToCart) {
                Text("Aggiungi al carrello")
            }
        }
    }
}

In questo esempio, la funzione Composable ProductItem accetta un oggetto Product, un modificatore e un callback. Tutti e tre i parametri sono immutabili, garantendo un comportamento prevedibile durante la ricomposizione. Il modificatore viene passato come parametro con un valore predefinito — questa è una pratica standard che consente al chiamante di personalizzare padding e dimensioni.

Componenti e modificatori nelle funzioni Composable

All'interno di una funzione Composable, vengono utilizzati componenti Material Design integrati (Text, Button, Card, TextField) o primitive fondamentali (Canvas, Layout). Ogni componente accetta parametri per configurare aspetto e comportamento, oltre a uno o più modificatori attraverso il parametro modifier.

I modificatori sono una catena di funzioni che modificano le dimensioni, la posizione, la gestione degli eventi e l'aspetto di un componente. L'ordine dei modificatori nella catena conta: clickable.semantics funziona diversamente da semantics.clickable, e padding.background colora sia l'area che lo sfondo includendo il padding, il che è fondamentale durante la progettazione.

All'interno di una funzione Composable, puoi utilizzare condizioni if e when per il rendering condizionale di parti dell'UI, nonché cicli for per liste dinamiche. Tutti questi costrutti funzionano naturalmente poiché Kotlin è un linguaggio di programmazione completo. Tuttavia, è importante ricordare: se una condizione o un ciclo contiene chiamate a funzioni Composable, anch'esse partecipano alla ricomposizione.

kotlin
@Composable
fun ProductList(
    products: List<Product>,
    modifier: Modifier = Modifier
) {
    LazyColumn(modifier = modifier) {
        items(products, key = { it.id }) { product ->
            ProductItem(
                product = product,
                onAddToCart = { /* add to cart */ }
            )
        }
    }
}

Esempi di funzioni Composable per schermi reali

Consideriamo un esempio di schermata di ricerca prodotti utilizzando diverse funzioni Composable. Qui vengono mostrati schemi tipici: un campo di input con stato, filtraggio dell'elenco, gestione dei risultati vuoti e caricamento.

kotlin
data class Product(
    val id: String,
    val name: String,
    val price: Double,
    val category: String
)

@Composable
fun SearchScreen() {
    var query by remember { mutableStateOf("") }
    val products = remember(query) { getFilteredProducts(query) }

    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        OutlinedTextField(
            value = query,
            onValueChange = { query = it },
            label = { Text("Cerca prodotti") },
            modifier = Modifier.fillMaxWidth()
        )

        Spacer(modifier = Modifier.height(16.dp))

        when (products) {
            is Loading -> CircularProgressIndicator()
            is Empty -> Text("Nessun risultato trovato")
            is Result -> LazyColumn {
                items(products.items, key = { it.id }) { product ->
                    ProductItem(product = product, onAddToCart = {})
                }
            }
        }
    }
}

Questo esempio dimostra diversi idiomi contemporaneamente: remember per preservare lo stato della query di ricerca, remember(query) per filtrare con una chiave, when per tre stati dell'UI e LazyColumn per il rendering efficiente delle liste. Ciascuno di questi idiomi è il risultato dell'esperienza pratica nello sviluppo di applicazioni Compose.

Parametri e Slot API

Le funzioni Composable accettano parametri proprio come le normali funzioni Kotlin, ma con una differenza importante: un parametro può essere un'altra funzione Composable passata tramite una lambda con annotazione @Composable. Questo meccanismo si chiama Slot API ed è il modello principale per creare contenitori riutilizzabili.

La Slot API risolve il problema che nel sistema View tradizionale veniva risolto attraverso ViewGroup e l'aggiunta programmatica di viste figlie. Invece dei metodi addView, Compose utilizza lambda content — l'ultimo parametro con tipo @Composable () -> Unit. Il chiamante passa qualsiasi UI in questa lambda e il contenitore definisce solo la sua disposizione.

I parametri delle funzioni Composable possono avere valori predefiniti, semplificandone l'uso in diversi contesti. Si raccomanda di rendere obbligatori solo i parametri senza i quali la funzione non può svolgere il suo compito e fornire valori predefiniti ragionevoli per gli altri.

ParametroTipoEsempio
ObbligatorioQualsiasi tiponame: String
OpzionaleCon valore predefinitomodifier: Modifier = Modifier
Content@Composable () -> Unitcontent: @Composable () -> Unit
CallbackLambda senza @ComposableonClick: () -> Unit

Idiomi delle funzioni Composable in Kotlin

Nella community di Compose sono emersi diversi idiomi consolidati che rendono le funzioni Composable più leggibili e prevedibili. Il primo è State Hoisting: lo stato viene sollevato a un livello superiore e la funzione Composable lo riceve tramite parametri. Questo rende la funzione pura e riutilizzabile in diversi contesti.

Il secondo idioma sono i parametri Event-driven. Invece di passare una ViewModel o useCase a una funzione Composable, vengono passati solo callback specifici: onSave, onDelete, onNavigateToDetail. Questo riduce l'accoppiamento e semplifica i test — un test per ProductItem non necessita di una ViewModel, solo di uno stub lambda.

Il terzo idioma è CompositionLocal per passare dati condivisi attraverso l'albero di composizione. Il tema, la densità dello schermo, il percorso corrente — tutto questo viene passato tramite CompositionLocal, evitando catene di parametri attraverso decine di funzioni Composable. Tuttavia, non bisogna abusare di CompositionLocal: i parametri espliciti sono sempre preferibili alle dipendenze implicite.

kotlin
// State Hoisting: stato sollevato alla funzione genitore
@Composable
fun CounterDisplay(
    count: Int,
    onIncrement: () -> Unit
) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Contatore: $count", style = MaterialTheme.typography.headlineLarge)
        Button(onClick = onIncrement) {
            Text("+1")
        }
    }
}

// Utilizzo con State Hoisting
@Composable
fun CounterScreen() {
    var count by remember { mutableStateOf(0) }
    CounterDisplay(
        count = count,
        onIncrement = { count++ }
    )
}

Domande frequenti

Si può usare return in una funzione Composable?

Sì, return è consentito, ma con cautela. Compose ottimizza la ricomposizione a livello di singole funzioni e un return anticipato può compromettere questa ottimizzazione. È meglio utilizzare operatori condizionali if o when all'interno del corpo della funzione.

In che cosa Unit-return differisce da void in Java?

In Kotlin, Unit è un oggetto singleton, non un tipo vuoto. Le funzioni Composable restituiscono Unit, il che tecnicamente significa che restituiscono l'oggetto Unit stesso. Tuttavia, in pratica questo non ha importanza — il valore restituito viene ignorato dal sistema di composizione.

Si può passare mutableListOf a una funzione Composable?

Passare collezioni mutabili è possibile, ma è una cattiva pratica. Se la collezione cambia, Compose non lo saprà perché il riferimento all'oggetto rimane lo stesso. Utilizza liste immutabili o mutableStateListOf per modifiche tracciate.

Come eseguire il debug di una funzione Composable?

Per il debug, utilizza Android Studio con Layout Inspector, che mostra l'albero corrente delle funzioni Composable, i valori dei parametri e le ragioni della ricomposizione. Anche il debugger normale di Kotlin funziona — i punti di interruzione all'interno delle funzioni Composable si attivano correttamente a ogni ricomposizione.

È obbligatorio specificare il tipo di ritorno di una funzione Composable?

Una funzione Composable restituisce sempre Unit, quindi il tipo di ritorno non viene specificato. Tentare di restituire un altro tipo causerà un errore di compilazione perché l'annotazione @Composable è incompatibile con tipi di ritorno non Unit.

Riepilogo

  • Composable Function — un blocco di costruzione dichiarativo dell'UI contrassegnato con @Composable
  • I parametri devono essere immutabili per una ricomposizione prevedibile
  • I modificatori e Slot API offrono flessibilità e riutilizzo senza ereditarietà
  • State Hoisting — sollevare lo stato verso l'alto per pulizia e testabilità
  • I callback Event-driven riducono l'accoppiamento con ViewModel e logica di business
  • CompositionLocal viene utilizzato per dati condivisi, ma i parametri espliciti sono preferibili
  • Gli idiomi di Compose rendono il codice prevedibile, testabile ed efficiente

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche