Specificare le dimensioni di una visualizzazione
Non è facile progettare un'interfaccia utente che sia coerente su dispositivi diversi, in quanto i dispositivi possono avere dimensioni e densità di pixel diverse. Basti pensare ai vari tipi di dispositivi disponibili: cellulare, tablet, desktop e altri. Come si crea un'interfaccia utente coerente in ognuno di questi dispositivi?
L'interfaccia utente dell'app multipiattaforma .NET (MAUI) offre i pannelli di layout per semplificare la creazione di interfacce utente coerenti. Il pannello di layout è responsabile del ridimensionamento e del posizionamento delle relative viste figlio. In questa unità si apprende il funzionamento del sistema di layout in .NET MAUI. In particolare, illustriamo il modo in cui le visualizzazioni vengono ridimensionate per impostazione predefinita e come richiedere una dimensione e una posizione specifiche per una visualizzazione in fase di esecuzione.
Che cos'è un pannello di layout?
Un pannello di layout è un contenitore di .NET MAUI che contiene una raccolta di visualizzazioni figlio e ne determina le dimensioni e la posizione. I pannelli di layout eseguono automaticamente il ricalcolo quando le dimensioni dell'app cambiano, ad esempio quando l'utente ruota il dispositivo.
Nota
Il termine visualizzazione o visualizzazione figlio fa riferimento a un controllo posizionato in un pannello di layout. Una visualizzazione può essere un'etichetta, un pulsante, un campo di immissione o qualsiasi altro tipo di elemento visivo supportato da .NET MAUI.
.NET MAUI offre diversi pannelli di layout tra cui scegliere. Ogni pannello gestisce le relative visualizzazioni figlio in modo diverso. La figura seguente illustra una panoramica concettuale di alcune delle opzioni più comuni.
StackLayout
: dispone le relative visualizzazioni figlio in una singola riga o colonna. Oltre aStackLayout
, è disponibile anche unVerticalStackLayout
ottimizzato eHorizontalStackLayout
quando non è necessario cambiare l'orientamento.AbsoluteLayout
: dispone le relative viste figlio usando le coordinate x e y.Grid
: dispone le viste figlio nelle celle create dall'intersezione di righe e colonne.FlexLayout
: dispone le visualizzazioni figlio come unStackLayout
, tranne per il fatto che è possibile andare a capo se non rientrano in una singola riga o colonna.
Nota
Esiste anche un quinto tipo di riquadro di layout denominato RelativeLayout
, che consente di specificare come disporre le visualizzazioni figlio una rispetto all'altra. È consigliabile usare il controllo FlexLayout
invece di RelativeLayout
perché le prestazioni sono migliori. RelativeLayout
è incluso in .NET MAUI per garantire la compatibilità con le versioni precedenti delle app Xamarin.
Il processo tipico di creazione di una pagina di .NET MAUI consiste nel creare un pannello di layout e quindi aggiungervi le visualizzazioni figlio. Aggiungendo una visualizzazione a un layout è possibile influenzarne le dimensioni e la posizione. L'ultima parola spetta però al pannello, in base ai suoi algoritmi di layout interni.
Prima di esaminare come si richiede una dimensione specifica per una vista, vediamo come il sistema di layout ridimensiona le viste per impostazione predefinita.
Dimensioni predefinite di una visualizzazione
Se non si specificano le dimensioni di una vista, queste aumentano automaticamente finché non sono sufficienti a ospitare tutto il contenuto. Si consideri ad esempio questo Extensible Application Markup Language (XAML):
<Label
Text="Hello"
BackgroundColor="Silver"
VerticalOptions="Center"
HorizontalOptions="Center"
FontSize="40"/>
Questo esempio definisce un'etichetta per visualizzare la parola Hello
su uno sfondo color argento. Poiché non si specificano le dimensioni, l'etichetta viene ridimensionata automaticamente per adattarsi alla parola Hello
. L'immagine seguente mostra il rendering dell'etichetta in un dispositivo Android:
Nota
È possibile impostare il colore di sfondo dell'etichetta per determinarne più facilmente le dimensioni in fase di esecuzione. È una buona tecnica di debug, da tenere presente durante la compilazione dell'interfaccia utente.
Specificare le dimensioni di una visualizzazione
Quando si compila un'interfaccia utente, è prassi comune voler controllare le dimensioni di una visualizzazione. Supponiamo ad esempio di voler creare una pagina di accesso in cui la larghezza del pulsante di accesso sia esattamente la metà della schermata. Se si usasse il ridimensionamento predefinito della visualizzazione, il pulsante avrebbe solo le dimensioni del testo Accedi. Le dimensioni non sono sufficienti, quindi è necessario specificarle manualmente.
La classe di base View
definisce due proprietà che determinano le dimensioni di una visualizzazione: WidthRequest
e HeightRequest
. WidthRequest
consente di specificare la larghezza e HeightRequest
l'altezza. Entrambe le proprietà sono di tipo double
.
Ecco un esempio che illustra come specificare la larghezza e l'altezza di un'etichetta nel codice XAML:
<Label
Text="Hello"
BackgroundColor="Silver"
VerticalOptions="Center"
HorizontalOptions="Center"
WidthRequest="100"
HeightRequest="300"
FontSize="40"/>
Il risultato è simile al seguente:
Nota
L'etichetta è ancora centrata, anche se il testo non è al centro dell'etichetta.
Un aspetto che vale la pena di notare sono i nomi di queste proprietà. Entrambe le proprietà contengono la parola request. Questa parola indica che il pannello di layout potrebbe non rispettare i valori della proprietà in fase di esecuzione. Il pannello di layout legge questi valori durante i calcoli di ridimensionamento e tenta di soddisfare le richieste, se possibile. Se non vi è spazio sufficiente, il pannello di layout può ignorare i valori.
Unità di misura
Quando si impostano WidthRequest
e HeightRequest
, si usano valori letterali come 100
. A livello di .NET MAUI, questi valori non hanno unità. Non sono punti o pixel. Sono semplicemente valori di tipo double
. .NET MAUI passa questi valori al sistema operativo sottostante in fase di esecuzione. È il sistema operativo che fornisce il contesto necessario per determinare il significato dei numeri:
- In iOS, i valori sono denominati punti.
- In Android, sono pixel indipendenti dalla densità.
Rendering delle dimensioni di una visualizzazione
Poiché spetta al pannello di layout determinare le dimensioni di una visualizzazione, non è possibile usare WidthRequest
e HeightRequest
per stabilire le dimensioni effettive in fase di esecuzione. Supponiamo ad esempio di impostare WidthRequest
su 100
per l'etichetta, ma il pannello non ha spazio sufficiente per soddisfare la richiesta. Il pannello imposta per l'etichetta una larghezza pari a 80
. Se a questo punto si controlla il valore della proprietà WidthRequest
, questa indica 100
, anche se il valore di rendering è 80
.
Per risolvere il problema, la classe di base View
definisce altre due proprietà denominate Width
e Height
. Queste proprietà sono di tipo double
e rappresentano la larghezza e l'altezza di una visualizzazione sottoposta a rendering. Utilizzare le proprietà Width
e Height
ogni volta che si recuperano le dimensioni di una visualizzazione.
Specificare la posizione di una visualizzazione
È necessario anche impostare la posizione di una visualizzazione. Tenere presente che nell'esempio della pagina di accesso le dimensioni del pulsante di accesso devono essere pari alla metà della larghezza della schermata. Poiché il pulsante di accesso non occupa l'intera larghezza della schermata, è disponibile un po' di spazio per spostarlo. Si potrebbe posizionarlo a sinistra, a destra o al centro della schermata.
La classe di base View
ha due proprietà che consentono di impostare la posizione di una visualizzazione: VerticalOptions
e HorizontalOptions
. Queste impostazioni determinano il modo in cui la visualizzazione viene posizionata all'interno del rettangolo ad essa allocato dal pannello di layout. È possibile specificare che si desidera che la vista sia allineata a uno dei quattro bordi del rettangolo. In alternativa, si desidera che occupi l'intero rettangolo.
Specificare un valore per VerticalOptions
o HorizontalOptions
è un'operazione più complessa rispetto all'impostazione delle dimensioni, in quanto si tratta di proprietà di tipo LayoutOptions
.
Che cos'è il tipo LayoutOptions?
LayoutOptions
è un tipo C# che incapsula due preferenze di layout, ossia Alignment
e Expands
. Entrambe le proprietà sono correlate al posizionamento, ma non sono correlate tra di loro. Ecco come appare la definizione del tipo:
public struct LayoutOptions
{
public LayoutAlignment Alignment { get; set; }
public bool Expands { get; set; }
...
}
Adesso, esaminiamo più attentamente Alignment
perché rappresenta l'opzione di layout più comune e intuitiva.
Che cos'è l'enumerazione LayoutAlignment?
LayoutAlignment
è un'enumerazione che contiene quattro valori: Start
, Center
, End
e Fill
. È possibile usare questi valori per controllare il posizionamento della visualizzazione figlio all'interno del rettangolo fornito dal relativo pannello di layout. Ad esempio, osservare il codice e lo screenshot di Android seguenti:
<StackLayout>
<Label Text="Start" HorizontalOptions="Start" BackgroundColor="Silver" FontSize="40" />
<Label Text="Center" HorizontalOptions="Center" BackgroundColor="Silver" FontSize="40" />
<Label Text="End" HorizontalOptions="End" BackgroundColor="Silver" FontSize="40"/>
<Label Text="Fill" HorizontalOptions="Fill" BackgroundColor="Silver" FontSize="40"/>
</StackLayout>
L’esempio usa uno StackLayout
verticale, quindi a ogni visualizzazione figlio è assegnata una riga. HorizontalOptions
determina la posizione della visualizzazione all'interno della riga corrispondente.
Che cos'è Expands?
La seconda proprietà dello struct LayoutOptions
è Expands
. La proprietà Expands
è un valore bool
che in Xamarin.Forms ha consentito a una visualizzazione in uno StackLayout
di richiedere spazio aggiuntivo, se disponibile. Questa proprietà è ora obsoleta e non viene più usata in .NET MAUI. Successivamente, esamineremo come ottenere lo stesso tipo di espansione nell'unità nel layout Grid
.