In questa parte della guida riprenderemo quanto detto all'inizio sull'esperienza utente delle applicazioni Windows RT ed esamineremo altri elementi importanti in grado di migliorare la user experience di applicazioni Windows Store per Windows 8 quali Semantic Zoom, Orientation, Form factor, Snap state, Tile, Toast.
Semantic Zoom
Semantic Zoom nasce con l'obiettivo di risolvere un problema nelle applicazioni touch-based: è estremamente scomodo, in una lista numerosa di informazioni, dover eseguire un gran numero di gesture di swipe per raggiungere la pagina di dati richiesta. Semantic Zoom si attiva con gesture di pinch e stretch ma, al posto di eseguire un semplice zoom ottico (gli elementi della lista diventerebbero solo più grandi e/o più piccoli) entra in una modalità raggruppata di tali elementi.
Un esempio dovrebbe chiarire il concetto, nella prossima immagine possiamo osservare la pagina che visualizza tutte le app presenti nel sistema (per raggiungere tale pagina è sufficiente aprire la Charm Bar e selezionare il comando Search, si veda l'articolo precedente per maggiori informazioni).
La precedente vista è la visualizzazione di default, chiamata "zoomed out", in sostanza si tratta l'intera lista espansa. Tramite una gesture di pinch sarà presentata la visualizzazione "zoomed in", come da prossima immagine.
È semplice comprendere che selezionando una lettera nel precendente esempio, la lista sarà espansa (attivando la modalità zoomed out) e lo scrolling si posizionerà in corrispondenza della lettera scelta.
I controlli del framework sono in grado di supportare tutte le modalità di input, e il controllo Semantic Zoom non è un'eccezione, è possibile infatti alternare le due visualizzazioni tramite mouse (nello specifico CTRL + Rotellina del mouse
) e da tastiera ( CTRL + '+' o '-'
).
Nota: se non si dispone di numeric pad occorre aggiungere il tasto SHIFT
alla sequenza. Segue una lista di sketch di utilizzi di Semantic Zoom, a sinistra la visualizzazione zoomed out e a destra la vista zoomed in.
Una ultima nota: il controllo Semantic Zoom ha solo due visualizzazioni, non è possibile utilizzarlo per rappresentare gerarchie complesse tramite diverse visualizzazioni intermedie.
Form factor
Anche se Windows RT nasce per i tablet, può essere installato su notebook, desktop, ultrabook etc. È fondamentale quindi progettare interfacce in grado di adattarsi alla risoluzione video e ai DPI del device.
Nell'implementazione dell'interfaccia dobbiamo evitare posizionamenti assoluti di controlli, ma privilegiare layout "fluidi", in grado di adattarsi a qualsiasi spazio a disposizione. La tecnica consigliata è progettare un singolo layout, non layout diversi in base al form factor, e usare controlli standard del framework come ad esempio GridView, in grado di fornire gratuitamente supporto per layout fluidi.
Nelle prossime immagini possiamo osservare lo stesso layout di una Windows Store App realizzato con il controllo GridView, visualizzato su device diversi su diverse risoluzioni video.
Un'interfaccia non è solo rappresentata dalla struttura dei controlli ma è composta da testo e da assets grafici (loghi, foto ecc.), nel primo caso non ci dobbiamo preoccupare perchè i font utilizzati nelle Windows Store App sono ad alti DPI quindi non hanno difficoltà ad adattarsi a form factor diversi, per gli asset invece abbiamo due strade, la prima è spostarsi verso asset vettoriali, elementi Path nel caso di runtime XAML o oggetti SVG nel caso di runtime Javascript, altrimenti se non è possibile (come nel caso di foto) la piattaforma offre una comoda soluzione: basta fornire tre versioni distinte dell'immagine con scaling al 100%, al 140% e al 180%, a runtime la piattaforma analizzerà il device in uso e caricherà l'asset più adatto.
Proviamo a chiarire con un esempio operativo questa ultima procedura: dato un file di partenza chiamato foto.jpg
realizziamo le tre versioni scalate e le nominiamo foto.scale-100.jpg
, foto.scale-140.jpg
e foto.scale-180.jpg
(il suffisso scale-xxx è ovviamente una convenzione obbligata). All'interno del sorgente XAML è sufficiente omettere il suffisso e lavorare con il nome originale.
<Image Source="foto.jpg" />
Nel caso di Windows Store App realizzate con HTML ovviamente il codice è il seguente:
<img src="foto.jpg" />
Portrait & Landscape
L'utente è solito di ruotare il proprio device tablet per fruire di un'applicazione in un modo a lui più familiare e naturale, dai test di usabilità è emerso che la discriminante fra un orientamento o l'altro è la tipologia di contenuto: un film è visualizzato solitamente in landscape mentre un documento è consultato in portrait per minimizzare gli scrolling.
Come sviluppatori o designer è nostro compito realizzare user interface in grado di adattarsi gradevolmente ai cambiamenti di orientamento, dal punto di vista tecnico con il runtime XAML tale funzionalità viene realizzata gestendo l'evento WindowSizeChanged e modificando gli stati della user interface tramite il classico VisualStateManager.
Nel seguente esempio possiamo analizzare un estratto di codice in grado di rappresentare lo stato dell'interfaccia a fronte della condizione di FullScreenPortrait, nello specifico viene reso visibile il controllo da visualizzare in portrait e reso invisibile il controllo da visualizzare in landscape, ovviamente il default della proprietà Visibility di tale controlli è inversa rispetto a questo esempio.
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="FullScreenPortrait">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ControlForLandscape" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ControlForPortrait" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
Per il framework HTML tale funzionalità viene implementata tramite media query, standard HTML5. Nel successivo estratto di codice sarà impostato il margine sinistro di un controllo a 120 pixel quando l'app si troverà nello stato di fullscreen-portrait:
@media screen and (-ms-view-state: fullscreen-portrait) {
.democontrol {
margin-left: 120px;
}
}
Come ultima annotazione è possibile abilitare e disabilitare il supporto per un dato orientamento a livello applicativo, tale opzione si trova nel file .appxmanifest
del progetto Visual Studio 2012.
Snap state
Oltre ai diversi form factor e ai cambiamenti di orientamento, Windows 8 prevede inoltre una ulteriore possibilità: lo stato snapped. Di default il sistema operativo mostrerà una sola applicazione in foreground ma è possibile tramite touch, mouse o tastiera affiancare all'applicazione principale una seconda app.
Nella prossima immagine l'applicazione Weather è stata affiancata un'app di consultazione di RSS, la prima si trova nello stato di filled mentre la seconda nello stato di snapped.
È importante comprendere che lo stato snapped non è una versione "gadget" di una app, ma una vera e propria instanza dell'app, solo con una larghezza ridotta, esattamente 320 pixel.
È buona regola implementare un gradevole e usabile stato di snapped, non è un semplice resize del layout principale ma dobbiamo ripensare l'esperienza complessiva, basti pensare al solo scrolling: in un'app fullscreen o filled è abitudine implementare lo scrolling orizzontale, mentre nello stato snapped lo scrolling è di solito esclusivamente verticale.
Se utilizziamo il framework XAML un controllo utile per layout verticali è la classe ListView, per cambiare user interface a fronte di un cambiamento di stato, sia esso fullscreen, filled o snapped, la metodologia è la stessa che abbiamo usato per l'orientamento: VisualStateManager.
Nel prossimo esempio analizziamo un estratto di codice XAML in grado di rappresentare la condizione dell'interfaccia nello stato di snapped, nello specifico il controllo GridView è reso invisibile mentre il controllo ListView viene reso visibile.
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="FullScreenPortrait"/>
<VisualState x:Name="Filled"/>
<VisualState x:Name="Snapped">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyListView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyGridView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>