Stili e temi

Prova il modo di comporre
Jetpack Compose è il toolkit per la UI consigliato per Android. Scopri come utilizzare i temi in Compose.

Gli stili e i temi su Android ti consentono di separare i dettagli della progettazione dell'app dalla struttura e dal comportamento della UI, in modo simile ai fogli di stile nella progettazione web.

Uno stile è un insieme di attributi che specifica l'aspetto di un singolo View. Uno stile può specificare attributi come colore del carattere, dimensione del carattere, colore di sfondo e molto altro.

Un tema è un insieme di attributi applicati a un'intera app, attività o gerarchia di visualizzazioni, non solo a una singola visualizzazione. Quando applichi un tema, ogni visualizzazione nell'app o attività applica ciascuno degli attributi del tema che supporta. I temi possono anche applicare stili a elementi non visibili, come la barra di stato e lo sfondo della finestra.

Gli stili e i temi vengono dichiarati in un file di risorse di stile in res/values/, in genere denominato styles.xml.

Figura 1. Due temi applicati alla stessa attività: Theme.AppCompat (a sinistra) e Theme.AppCompat.Light (a destra).

Confronto tra temi e stili

I temi e gli stili hanno molte somiglianze, ma vengono utilizzati per scopi diversi. I temi e gli stili hanno la stessa struttura di base: una coppia chiave-valore che mappa gli attributi alle risorse.

Uno stile specifica gli attributi per un determinato tipo di visualizzazione. Ad esempio, uno stile potrebbe specificare gli attributi di un pulsante. Ogni attributo specificato in uno stile è un attributo che puoi impostare nel file di layout. L'estrazione di tutti gli attributi in uno stile semplifica l'utilizzo e la manutenzione in più widget.

Un tema definisce una raccolta di risorse denominate a cui è possibile fare riferimento in stili, layout, widget e così via. I temi assegnano nomi semantici, come colorPrimary, alle risorse Android.

Stili e temi sono pensati per essere usati insieme. Ad esempio, potresti avere uno stile che specifica che una parte di un pulsante è colorPrimary e un'altra parte è colorSecondary. Le definizioni effettive di questi colori sono fornite nel tema. Quando il dispositivo passa alla modalità notturna, la tua app può passare dal tema "chiaro" a quello "scuro", modificando i valori di tutti i nomi delle risorse. Non devi modificare gli stili, poiché utilizzano i nomi semantici e non definizioni di colore specifiche.

Per ulteriori informazioni su come funzionano insieme temi e stili, consulta il post del blog Android styling: themes vs styles.

Creare e applicare uno stile

Per creare un nuovo stile, apri il file res/values/styles.xml del progetto. Per ogni stile che vuoi creare, segui questi passaggi:

  1. Aggiungi un elemento <style> con un nome che identifichi in modo univoco lo stile.
  2. Aggiungi un elemento <item> per ogni attributo di stile che vuoi definire. L'elemento name in ogni elemento specifica un attributo che altrimenti utilizzi come attributo XML nel tuo layout. Il valore nell'elemento <item> è il valore di questo attributo.

Ad esempio, supponiamo di definire lo stile seguente:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="GreenText" parent="TextAppearance.AppCompat">
        <item name="android:textColor">#00FF00</item>
    </style>
</resources>

Puoi applicare lo stile a una visualizzazione nel seguente modo:

<TextView
    style="@style/GreenText"
    ... />

Ogni attributo specificato nello stile viene applicato a quella vista se la vista lo accetta. La visualizzazione ignora tutti gli attributi che non accetta.

Tuttavia, anziché applicare uno stile alle singole visualizzazioni, in genere applichi gli stili come tema per l'intera app, attività o raccolta di visualizzazioni, come descritto in un'altra sezione di questa guida.

Estendere e personalizzare uno stile

Quando crei i tuoi stili, estendi sempre uno stile esistente dal framework o dalla libreria di supporto in modo da mantenere la compatibilità con gli stili dell'interfaccia utente della piattaforma. Per estendere uno stile, specifica lo stile da estendere con l'attributo parent. Puoi quindi sostituire gli attributi di stile ereditati e aggiungerne di nuovi.

Ad esempio, puoi ereditare l'aspetto predefinito del testo della piattaforma Android e modificarlo come segue:

<style name="GreenText" parent="@android:style/TextAppearance">
    <item name="android:textColor">#00FF00</item>
</style>

Tuttavia, eredita sempre gli stili principali dell'app dalla libreria di supporto Android. Gli stili nella libreria di supporto forniscono compatibilità ottimizzando ogni stile per gli attributi dell'interfaccia utente disponibili in ogni versione. Gli stili della libreria di assistenza spesso hanno un nome simile allo stile della piattaforma, ma con l'aggiunta di AppCompat.

Per ereditare gli stili da una libreria o dal tuo progetto, dichiara il nome dello stile principale senza la parte @android:style/ mostrata nell'esempio precedente. Ad esempio, il seguente esempio eredita gli stili di aspetto del testo dalla libreria di supporto:

<style name="GreenText" parent="TextAppearance.AppCompat">
    <item name="android:textColor">#00FF00</item>
</style>

Puoi anche ereditare gli stili, ad eccezione di quelli della piattaforma, estendendo il nome di uno stile con una notazione con punti, anziché utilizzare l'attributo parent. ovvero anteponi al nome dello stile il nome dello stile da ereditare, separato da un punto. In genere, questa operazione viene eseguita solo quando si estendono i propri stili, non quelli di altre librerie. Ad esempio, lo stile seguente eredita tutti gli stili di GreenText nell'esempio precedente e poi aumenta la dimensione del testo:

<style name="GreenText.Large">
    <item name="android:textSize">22dp</item>
</style>

Puoi continuare a ereditare stili come questo tutte le volte che vuoi concatenando altri nomi.

Per scoprire quali attributi puoi dichiarare con un tag <item>, consulta la tabella "Attributi XML" nei vari riferimenti alle classi. Tutte le visualizzazioni supportano gli attributi XML della classe View di base e molte visualizzazioni aggiungono i propri attributi speciali. Ad esempio, gli attributi XML TextView includono l'attributo android:inputType che puoi applicare a una visualizzazione di testo che riceve input, ad esempio un widget EditText.

Applicare uno stile come tema

Puoi creare un tema nello stesso modo in cui crei gli stili. La differenza sta nel modo in cui lo applichi: anziché applicare uno stile con l'attributo style a una visualizzazione, applichi un tema con l'attributo android:theme al tag <application> o a un tag <activity> nel file AndroidManifest.xml.

Ad esempio, ecco come applicare il tema "scuro" di Material Design della libreria di supporto Android all'intera app:

<manifest ... >
    <application android:theme="@style/Theme.AppCompat" ... >
    </application>
</manifest>

Ecco come applicare il tema "Chiaro" a una sola attività:

<manifest ... >
    <application ... >
        <activity android:theme="@style/Theme.AppCompat.Light" ... >
        </activity>
    </application>
</manifest>

Ogni visualizzazione nell'app o nell'attività applica gli stili supportati tra quelli definiti nel tema specificato. Se una visualizzazione supporta solo alcuni degli attributi dichiarati nello stile, applica solo questi attributi e ignora quelli che non supporta.

A partire da Android 5.0 (livello API 21) e dalla libreria di supporto Android v22.1, puoi anche specificare l'attributo android:theme per una visualizzazione nel file di layout. In questo modo viene modificato il tema per quella visualizzazione e per le visualizzazioni secondarie, il che è utile per modificare le tavolozze dei colori del tema in una parte specifica dell'interfaccia.

Gli esempi precedenti mostrano come applicare un tema come Theme.AppCompat fornito dalla libreria di supporto Android. Tuttavia, in genere vuoi personalizzare il tema in modo che si adatti al brand della tua app. Il modo migliore per farlo è estendere questi stili dalla libreria di supporto ed eseguire l'override di alcuni attributi, come descritto nella sezione seguente.

Gerarchia degli stili

Android offre diversi modi per impostare gli attributi nell'app Android. Ad esempio, puoi impostare gli attributi direttamente in un layout, applicare uno stile a una visualizzazione, applicare un tema a un layout e persino impostare gli attributi in modo programmatico.

Quando scegli come definire lo stile dell'app, tieni presente la gerarchia degli stili di Android. In generale, utilizza temi e stili il più possibile per garantire la coerenza. Se specifichi gli stessi attributi in più posizioni, il seguente elenco determina quali attributi vengono applicati alla fine. L'elenco è ordinato dalla precedenza più alta a quella più bassa.

  1. Applicazione di stili a livello di carattere o paragrafo utilizzando intervalli di testo alle classi derivate da TextView.
  2. Applicazione degli attributi in modo programmatico.
  3. Applicare singoli attributi direttamente a una visualizzazione.
  4. Applicare uno stile a una vista.
  5. Stile predefinito.
  6. Applicare un tema a una raccolta di visualizzazioni, a un'attività o all'intera app.
  7. Applicazione di determinati stili specifici per la visualizzazione, ad esempio l'impostazione di un TextAppearance su un TextView.

Figura 2. Lo stile di un span sostituisce lo stile di un textAppearance.

TextAppearance

Un limite degli stili è che puoi applicarne uno solo a un View. In un TextView, tuttavia, puoi anche specificare un attributo TextAppearance che funziona in modo simile a uno stile, come mostrato nell'esempio seguente:

<TextView
    ...
    android:textAppearance="@android:style/TextAppearance.Material.Headline"
    android:text="This text is styled via textAppearance!" />

TextAppearance ti consente di definire uno stile specifico per il testo, lasciando lo stile di un View disponibile per altri usi. Tieni presente, tuttavia, che se definisci attributi di testo direttamente su View o in uno stile, questi valori sostituiscono i valori TextAppearance.

TextAppearance supporta un sottoinsieme di attributi di stile offerti da TextView. Per l'elenco completo degli attributi, vedi TextAppearance.

Alcuni attributi TextView comuni non inclusi sono lineHeight[Multiplier|Extra], lines, breakStrategy e hyphenationFrequency. TextAppearance funziona a livello di carattere e non di paragrafo, pertanto gli attributi che influiscono sull'intero layout non sono supportati.

Personalizzare il tema predefinito

Quando crei un progetto con Android Studio, viene applicato un tema Material Design alla tua app per impostazione predefinita, come definito nel file styles.xml del progetto. Questo stile AppTheme estende un tema della Support Library e include override per gli attributi di colore utilizzati da elementi chiave dell'interfaccia utente, come la barra dell'app e il pulsante di azione mobile, se utilizzato. In questo modo, puoi personalizzare rapidamente il design dei colori della tua app aggiornando i colori forniti.

Ad esempio, il file styles.xml ha un aspetto simile a questo:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

I valori di stile sono in realtà riferimenti ad altre risorse di colore, definite nel file res/values/colors.xml del progetto. Questo è il file che modifichi per cambiare i colori. Consulta la panoramica dei colori di Material Design per migliorare l'esperienza utente con colori dinamici e colori personalizzati aggiuntivi.

Una volta che conosci i colori, aggiorna i valori in res/values/colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--   Color for the app bar and other primary UI elements. -->
    <color name="colorPrimary">#3F51B5</color>

    <!--   A darker variant of the primary color, used for
           the status bar (on Android 5.0+) and contextual app bars. -->
    <color name="colorPrimaryDark">#303F9F</color>

    <!--   a secondary color for controls like checkboxes and text fields. -->
    <color name="colorAccent">#FF4081</color>
</resources>

Puoi quindi sostituire gli altri stili che preferisci. Ad esempio, puoi modificare il colore di sfondo dell'attività nel seguente modo:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="android:windowBackground">@color/activityBackground</item>
</style>

Per un elenco degli attributi che puoi utilizzare nel tema, consulta la tabella degli attributi all'indirizzo R.styleable.Theme. Quando aggiungi gli stili per le visualizzazioni nel layout, puoi trovare gli attributi anche esaminando la tabella "Attributi XML" nei riferimenti alla classe di visualizzazione. Ad esempio, tutte le visualizzazioni supportano gli attributi XML della classe View di base.

La maggior parte degli attributi viene applicata a tipi specifici di visualizzazioni, mentre alcuni si applicano a tutte le visualizzazioni. Tuttavia, alcuni attributi del tema elencati in R.styleable.Theme si applicano alla finestra dell'attività, non alle visualizzazioni nel layout. Ad esempio, windowBackground modifica lo sfondo della finestra e windowEnterTransition definisce un'animazione di transizione da utilizzare all'avvio dell'attività. Per maggiori dettagli, vedi Avviare un'attività utilizzando un'animazione.

Android Support Library fornisce anche altri attributi che puoi utilizzare per personalizzare il tema esteso da Theme.AppCompat, come l'attributo colorPrimary mostrato nell'esempio precedente. Questi dati sono visualizzabili al meglio nel file attrs.xml della raccolta.

Nella libreria di assistenza sono disponibili anche temi diversi che potresti voler estendere anziché quelli mostrati nell'esempio precedente. Il posto migliore per vedere i temi disponibili è il file themes.xml della raccolta.

Aggiungere stili specifici per la versione

Se una nuova versione di Android aggiunge attributi del tema che vuoi utilizzare, puoi aggiungerli al tema mantenendo la compatibilità con le versioni precedenti. Tutto ciò che ti serve è un altro file styles.xml salvato in una directory values che include il qualificatore della versione della risorsa:

res/values/styles.xml        # themes for all versions
res/values-v21/styles.xml    # themes for API level 21+ only

Poiché gli stili nel file values/styles.xml sono disponibili per tutte le versioni, i tuoi temi in values-v21/styles.xml possono ereditarli. Ciò significa che puoi evitare di duplicare gli stili iniziando con un tema "base" e poi estendendolo negli stili specifici della versione.

Ad esempio, per dichiarare le transizioni delle finestre per Android 5.0 (livello API 21) e versioni successive, devi utilizzare nuovi attributi. Pertanto, il tema di base in res/values/styles.xml può avere questo aspetto:

<resources>
    <!-- Base set of styles that apply to all versions. -->
    <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/primaryColor</item>
        <item name="colorPrimaryDark">@color/primaryTextColor</item>
        <item name="colorAccent">@color/secondaryColor</item>
    </style>

    <!-- Declare the theme name that's actually applied in the manifest file. -->
    <style name="AppTheme" parent="BaseAppTheme" />
</resources>

Poi, aggiungi gli stili specifici della versione in res/values-v21/styles.xml, come segue:

<resources>
    <!-- extend the base theme to add styles available only with API level 21+ -->
    <style name="AppTheme" parent="BaseAppTheme">
        <item name="android:windowActivityTransitions">true</item>
        <item name="android:windowEnterTransition">@android:transition/slide_right</item>
        <item name="android:windowExitTransition">@android:transition/slide_left</item>
    </style>
</resources>

Ora puoi applicare AppTheme nel file manifest e il sistema seleziona gli stili disponibili per ogni versione del sistema.

Per saperne di più sull'utilizzo di risorse alternative per dispositivi diversi, vedi Fornire risorse alternative.

Personalizzare gli stili dei widget

Ogni widget nel framework e nella libreria di supporto ha uno stile predefinito. Ad esempio, quando applichi uno stile alla tua app utilizzando un tema della Support Library, un'istanza di Button viene stilizzata utilizzando lo stile Widget.AppCompat.Button. Se vuoi applicare uno stile diverso a un widget di un pulsante, puoi farlo con l'attributo style nel file di layout. Ad esempio, il codice seguente applica lo stile del pulsante senza bordi della libreria:

<Button
    style="@style/Widget.AppCompat.Button.Borderless"
    ... />

Se vuoi applicare questo stile a tutti i pulsanti, puoi dichiararlo in buttonStyle del tema nel seguente modo:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="buttonStyle">@style/Widget.AppCompat.Button.Borderless</item>
    ...
</style>

Puoi anche estendere gli stili dei widget, proprio come estendere qualsiasi altro stile, e poi applicare lo stile personalizzato del widget nel layout o nel tema.

Risorse aggiuntive

Per saperne di più su temi e stili, consulta le seguenti risorse aggiuntive:

Post del blog