Visualizza l'anteprima dell'interfaccia utente con le anteprime componibili

Un composable è definito da una funzione e annotato con @Composable:

@Composable
fun SimpleComposable() {
    Text("Hello World")
}

Un semplice elemento di testo contenente le parole "Hello World"

Per abilitare un'anteprima di questo composable, creane un altro, annotato con @Composable e @Preview. Questo nuovo composable annotato ora contiene il composable che hai creato inizialmente, SimpleComposable:

@Preview
@Composable
fun SimpleComposablePreview() {
    SimpleComposable()
}

L'annotazione @Preview indica ad Android Studio che questo componibile deve essere mostrato nella visualizzazione struttura di questo file. Puoi visualizzare gli aggiornamenti in tempo reale dell'anteprima componibile man mano che apporti le modifiche.

Una GIF che mostra gli aggiornamenti in tempo reale utilizzando l'anteprima di Compose

Puoi aggiungere manualmente i parametri nel codice per personalizzare il modo in cui Android Studio esegue il rendering di @Preview. Puoi anche aggiungere l'annotazione @Preview alla stessa funzione più volte per visualizzare l'anteprima di un composable con proprietà diverse.

Uno dei principali vantaggi dell'utilizzo dei componibili @Preview è evitare di fare affidamento sull'emulatore in Android Studio. Puoi salvare l'avvio dell'emulatore, che richiede molta memoria, per modifiche più definitive all'aspetto e alla funzionalità e sfruttare la capacità di @Preview di apportare e testare facilmente piccole modifiche al codice.

Per sfruttare l'annotazione @Preview nel modo più efficace, assicurati di definire le schermate in termini di stato che ricevono come input e di eventi che generano come output.

Definisci il @Preview

Android Studio offre alcune funzionalità per estendere le anteprime componibili. Puoi modificare il design del container, interagire con loro o eseguirne il deployment direttamente su un emulatore o un dispositivo.

Dimensioni

Per impostazione predefinita, le dimensioni di @Preview vengono scelte automaticamente per adattarsi ai contenuti. Per impostare le dimensioni manualmente, aggiungi i parametri heightDp e widthDp. Questi valori vengono già interpretati come dp, quindi non è necessario aggiungere .dp:

@Preview(widthDp = 50, heightDp = 50)
@Composable
fun SquareComposablePreview() {
    Box(Modifier.background(Color.Yellow)) {
        Text("Hello World")
    }
}

Un quadrato giallo con la scritta "Hello World"

Anteprima colore dinamico

Se hai attivato il colore dinamico nella tua app, utilizza l'attributo wallpaper per cambiare gli sfondi e vedere come reagisce la UI allo sfondo scelto da utenti diversi. Seleziona uno dei diversi temi per lo sfondo offerti dalla classe Wallpaper. Questa funzionalità richiede Compose 1.4.0 o versioni successive.

Utilizzo con dispositivi diversi

In Android Studio Flamingo, puoi modificare il parametro device dell'annotazione Preview per definire le configurazioni dei tuoi componibili su diversi dispositivi.

Funzione componibile di esempio

Quando il parametro del dispositivo ha una stringa vuota (@Preview(device = "")), puoi richiamare il completamento automatico premendo Ctrl + Space. Poi, puoi impostare i valori di ogni parametro.

Modifica della funzione di esempio

Dal completamento automatico, puoi selezionare qualsiasi opzione del dispositivo dall'elenco, ad esempio @Preview(device = "id:pixel_4"). In alternativa, puoi inserire un dispositivo personalizzato scegliendo spec:width=px,height=px,dpi=int… per impostare i singoli valori di ogni parametro.

Elenco
delle specifiche

Per applicare, premi Enter o annulla con Esc.

Se imposti un valore non valido, la dichiarazione viene sottolineata in rosso e potrebbe essere disponibile una correzione (Alt + Enter (⌥ + ⏎ per macOS) > Sostituisci con…. L'ispezione tenta di fornire una correzione che assomigli il più possibile al tuo input.

Esempio di valore non valido

Impostazioni internazionali

Per testare diverse impostazioni internazionali degli utenti, aggiungi il parametro locale:

@Preview(locale = "fr-rFR")
@Composable
fun DifferentLocaleComposablePreview() {
    Text(text = stringResource(R.string.greeting))
}

Un semplice elemento di testo contenente la parola "Bonjour" con una bandiera francese

Imposta colore di sfondo

Per impostazione predefinita, il composable viene visualizzato con uno sfondo trasparente. Per aggiungere uno sfondo, aggiungi i parametri showBackground e backgroundColor. Tieni presente che backgroundColor è un Long ARGB, non un valore Color:

@Preview(showBackground = true, backgroundColor = 0xFF00FF00)
@Composable
fun WithGreenBackground() {
    Text("Hello World")
}

Un rettangolo verde con il testo "Hello World"

UI di sistema

Se devi visualizzare le barre di stato e delle azioni all'interno di un'anteprima, aggiungi il parametro showSystemUi:

@Preview(showSystemUi = true)
@Composable
fun DecoratedComposablePreview() {
    Text("Hello World")
}

Una finestra di anteprima che mostra un'attività con le barre di stato e delle azioni.

Modalità UI

Il parametro uiMode può assumere una qualsiasi delle costanti Configuration.UI_* e ti consente di modificare il comportamento dell'anteprima di conseguenza. Ad esempio, puoi impostare l'anteprima sulla modalità notturna per vedere come reagisce il tema.

UI di anteprima di Compose

LocalInspectionMode

Puoi leggere da LocalInspectionMode CompositionLocal per vedere se il composable viene visualizzato in un'anteprima (all'interno di un componente ispezionabile). Se la composizione viene visualizzata in un'anteprima, LocalInspectionMode.current restituisce true. Queste informazioni ti consentono di personalizzare l'anteprima. Ad esempio, puoi mostrare un'immagine segnaposto nella finestra di anteprima anziché i dati reali.

In questo modo, puoi anche aggirare le limitazioni. Ad esempio, mostrando dati campionati anziché chiamare la richiesta di rete.

@Composable
fun GreetingScreen(name: String) {
    if (LocalInspectionMode.current) {
        // Show this text in a preview window:
        Text("Hello preview user!")
    } else {
        // Show this text in the app:
        Text("Hello $name!")
    }
}

Interagisci con @Preview

Android Studio offre funzionalità che ti consentono di interagire con le anteprime definite. Questa interazione ti aiuta a comprendere il comportamento di runtime delle anteprime e ti consente di navigare meglio nella UI con le anteprime.

modalità interattiva

La modalità interattiva ti consente di interagire con un'anteprima in modo simile a come faresti su un dispositivo che esegue il tuo programma, ad esempio uno smartphone o un tablet. La modalità interattiva è isolata in un ambiente sandbox (ovvero isolata da altre anteprime), in cui puoi fare clic sugli elementi e inserire l'input utente nell'anteprima. È un modo rapido per testare diversi stati, gesti e persino animazioni del composable.

L'utente fa clic sul pulsante "interattivo" dell'anteprima

Un video dell'utente che interagisce con un'anteprima

Navigazione del codice e strutture componibili

Puoi passare il mouse sopra un'anteprima per visualizzare i contorni dei composabili contenuti all'interno. Se fai clic su una struttura componibile, la visualizzazione dell'area di modifica passa alla relativa definizione.

L'utente passa il mouse sopra un'anteprima, facendo sì che Studio mostri i contorni dei suoi elementi componibili

Esegui anteprima

Puoi eseguire un @Preview specifico su un emulatore o un dispositivo fisico. Il deployment dell'anteprima viene eseguito all'interno della stessa app del progetto come nuovo Activity, quindi condivide lo stesso contesto e le stesse autorizzazioni. Non è necessario scrivere codice boilerplate per richiedere un'autorizzazione se è già stata concessa.

Fai clic sull'icona Esegui anteprima Esegui anteprima
icon accanto all'annotazione @Preview o nella parte superiore dell'anteprima. Android Studio esegue il deployment di @Preview sul dispositivo connesso o sull'emulatore.

L'utente che fa clic sull'anteprima

Video dell'utente che esegue il deployment di un'anteprima sul
dispositivo

Copia il rendering @Preview

Ogni anteprima visualizzata può essere copiata come immagine facendo clic con il tasto destro del mouse.

L'utente fa clic su un'anteprima per copiarla come immagine.

Più anteprime della stessa annotazione @Preview

Puoi mostrare più versioni dello stesso composable @Preview con specifiche diverse o parametri diversi passati al composable. In questo modo, puoi ridurre il codice boilerplate che altrimenti dovresti scrivere.

Modelli di anteprima multipla

androidx.compose.ui:ui-tooling-preview 1.6.0-alpha01+ introduce i modelli di API Multipreview: @PreviewScreenSizes, @PreviewFontScales, @PreviewLightDark e @PreviewDynamicColors, in modo che con una singola annotazione puoi visualizzare l'anteprima della UI di Compose in scenari comuni.

Visualizzare l'anteprima di diversi caratteri e dimensioni dello schermo utilizzando i modelli

Crea annotazioni di anteprima multipla personalizzate

Con l'anteprima multipla, puoi definire una classe di annotazione che ha a sua volta più annotazioni @Preview con configurazioni diverse. L'aggiunta di questa annotazione a una funzione componibile esegue automaticamente il rendering di tutte le diverse anteprime contemporaneamente. Ad esempio, puoi utilizzare questa annotazione per visualizzare l'anteprima di più dispositivi, dimensioni dei caratteri o temi contemporaneamente senza ripetere queste definizioni per ogni singolo componibile.

Inizia creando la tua classe di annotazione personalizzata:

@Preview(
    name = "small font",
    group = "font scales",
    fontScale = 0.5f
)
@Preview(
    name = "large font",
    group = "font scales",
    fontScale = 1.5f
)
annotation class FontScalePreviews

Puoi utilizzare questa annotazione personalizzata per i tuoi elementi componibili di anteprima:

@FontScalePreviews
@Composable
fun HelloWorldPreview() {
    Text("Hello World")
}

Scheda di progettazione di Android Studio che mostra il componibile con caratteri piccoli e grandi

Puoi combinare più annotazioni di anteprima multipla e annotazioni di anteprima normali per creare un insieme più completo di anteprime. La combinazione di annotazioni multipreview non significa che vengano mostrate tutte le diverse combinazioni. Invece, ogni annotazione di anteprima multipla agisce in modo indipendente e visualizza solo le proprie varianti.

@Preview(
    name = "Spanish",
    group = "locale",
    locale = "es"
)
@FontScalePreviews
annotation class CombinedPreviews

@CombinedPreviews
@Composable
fun HelloWorldPreview2() {
    MaterialTheme { Surface { Text(stringResource(R.string.hello_world)) } }
}

Scheda di progettazione di Android Studio che mostra il composable in tutte le configurazioni

La natura combinabile dell'anteprima multipla e dell'anteprima normale ti consente di testare in modo più completo molte proprietà di progetti su larga scala.

@Preview e set di dati di grandi dimensioni

Molto spesso, sorge la necessità di passare un set di dati di grandi dimensioni all'anteprima componibile. Per farlo, basta passare i dati campionati a una funzione di anteprima componibile aggiungendo un parametro con l'annotazione @PreviewParameter.

@Preview
@Composable
fun UserProfilePreview(
    @PreviewParameter(UserPreviewParameterProvider::class) user: User
) {
    UserProfile(user)
}

Per fornire i dati campionati, crea una classe che implementi PreviewParameterProvider e restituisca i dati campionati come sequenza.

class UserPreviewParameterProvider : PreviewParameterProvider<User> {
    override val values = sequenceOf(
        User("Elise"),
        User("Frank"),
        User("Julia")
    )
}

In questo modo viene visualizzata un'anteprima per ogni elemento di dati nella sequenza:

Anteprime che mostrano gli elementi componibili Elise, Frank e Julia

Puoi utilizzare la stessa classe provider per più anteprime. Se necessario, limita il numero di anteprime impostando il parametro limit.

@Preview
@Composable
fun UserProfilePreview2(
    @PreviewParameter(UserPreviewParameterProvider::class, limit = 2) user: User
) {
    UserProfile(user)
}

Per impostazione predefinita, le anteprime che utilizzano @PreviewParameter vengono denominate utilizzando l'indice del parametro e il nome della proprietà (utente 0, utente 1, utente 2 e così via), il che può rendere difficile distinguerle. Per migliorare la chiarezza dell'anteprima, puoi fornire nomi visualizzati personalizzati per ogni anteprima eseguendo l'override di getDisplayName() nel tuo PreviewParameterProvider. In questo modo è possibile distinguere tra diverse varianti di dati o stati della UI. Ad esempio, puoi etichettare le anteprime in base ai dati di input:

class UserAgePreviewParameterProvider : PreviewParameterProvider<User> {
    // Using a List internally for efficient index-based access
    private val userList = listOf(
        User(name = "Elise", age = 30),
        User(name = "Frank", age = 31),
        User(name = "Julia", age = 40)
    )

    override val values = userList.asSequence()

    override fun getDisplayName(index: Int): String? {
        // Return null or an empty string to use the default index-based name
        val user = userList.getOrNull(index) ?: return null
        return "${user.name} - ${user.age}"
    }
}

Anteprime con nomi visualizzati personalizzati che mostrano i componibili Elise - 30, Frank - 31 e Julia - 40

Generazione di anteprime assistita dall'AI

L'agente AI in Android Studio può generare automaticamente anteprime di Compose per i tuoi componibili. Fai clic con il tasto destro del mouse su una funzione componibile e seleziona AI > Genera anteprima per [nome componibile]. L'agente analizza il composable per generare il boilerplate @Preview necessario con i parametri corretti, aiutandoti a verificare rapidamente che l'interfaccia utente venga visualizzata come previsto.

Genera un'anteprima di Compose utilizzando l'AI.

Classe di annotazione @Preview

Puoi sempre premere "Ctrl o ⌘ + clic" sull'annotazione @Preview in Android Studio per visualizzare un elenco completo dei parametri che possono essere modificati durante la personalizzazione dell'anteprima.

annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    val widthDp: Int = -1,
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) val fontScale: Float = 1f,
    val showSystemUi: Boolean = false,
    val showBackground: Boolean = false,
    val backgroundColor: Long = 0,
    @UiMode val uiMode: Int = 0,
    @Device val device: String = Devices.DEFAULT,
    @Wallpaper val wallpaper: Int = Wallpapers.NONE,
)

Limitazioni e best practice

Android Studio esegue il codice delle anteprime direttamente nell'area di anteprima. Non richiede l'esecuzione di un emulatore o di un dispositivo fisico perché sfrutta una parte trasferita del framework Android chiamata Layoutlib. Layoutlib è una versione personalizzata del framework Android progettata per essere eseguita al di fuori dei dispositivi Android. L'obiettivo della libreria è fornire un'anteprima di un layout in Android Studio che sia molto simile al rendering sui dispositivi.

Limitazioni delle anteprime

Grazie al modo in cui vengono eseguite le anteprime in Android Studio, sono leggere e non richiedono l'intero framework Android per il rendering. Tuttavia, questo comporta le seguenti limitazioni:

  • Nessun accesso di rete
  • Nessun accesso ai file
  • Alcune API Context potrebbero non essere completamente disponibili

Anteprime e ViewModels

Le anteprime sono limitate quando utilizzi ViewModel all'interno di un composable. Il sistema di anteprime non è in grado di creare tutti i parametri passati a un ViewModel, come repository, casi d'uso, gestori o simili. Inoltre, se ViewModel partecipa all'inserimento delle dipendenze (ad esempio con Hilt), il sistema di anteprime non può creare l'intero grafico delle dipendenze per creare ViewModel.

Quando provi a visualizzare l'anteprima di un componibile con ViewModel, Android Studio mostra un errore durante il rendering del componibile specifico:

Riquadro dei problemi di Android Studio con il messaggio &quot;Impossibile creare un'istanza di un messaggio &quot;ViewModel&quot;&quot;

Se vuoi visualizzare l'anteprima di un composable che utilizza un ViewModel, devi creare un altro composable con i parametri di ViewModel passati come argomenti del composable. In questo modo, non è necessario visualizzare l'anteprima del componibile che utilizza ViewModel.

@Composable
fun AuthorScreen(viewModel: AuthorViewModel = viewModel()) {
  AuthorScreen(
    name = viewModel.authorName,
    // ViewModel sends the network requests and makes posts available as a state
    posts = viewModel.posts
  )
}

@Composable
fun AuthorScreen(
  name: NameLabel,
  posts: PostsList
) {
  // ...
}

@Preview
@Composable
fun AuthorScreenPreview(
  // You can use some sample data to preview your composable without the need to construct the ViewModel
  name: String = sampleAuthor.name,
  posts: List<Post> = samplePosts[sampleAuthor]
) {
  AuthorScreen(
      name = NameLabel(name),
      posts = PostsList(posts)
  )
}

Risorse aggiuntive