Oggi sono innumerevoli i dispositivi sul mercato dotati di uno schermo touch, con dimensioni che variano da quelle più piccole degli smartphone (dai 5.1 pollici in giù) a quelle "medie" dei cosiddetti phablet (inferiori a 7 pollici), crescendo sui tablet (da 7 a 10.1 pollici) e finendo con Ultrabook e dispositivi "All-In-One", ossia che combinano le caratteristiche di device diversi all'interno di un unico prodotto, permettendo ad esempio di sganciare il display dalla tastiera del laptop trasformando istantaneamente il touch screen in un tablet.
Per i produttori di software e di sistemi operativi è indispensabile quindi supportare appieno l'uso dei touch screen, in primo luogo, ma anche adattarsi all'estrema varietà di schermi disponibili e diversificati oltreché per dimensione anche per la destinazione d'uso, come avviene nei dispositivi "All-In-One".
L'eterogeneità dei "form factor" rappresenta una difficile sfida per gli sviluppatori, ma anche un'opportunità interessante da cogliere se si vogliono realizzare app che siano sempre più a misura d'uomo.
I requisiti
Se si decide di intraprendere questo percorso, la progettazione dell'app e in particolare della sua interfaccia grafica deve tenere conto di alcuni requisiti importanti; ne riporto un elenco non esaustivo:
- giusta dimensione dei controlli visuali: i controlli con i quali l'utente interagisce (pulsanti, caselle di testo, checkbox, menu, icone, ecc.) devono essere sufficientemente grandi per poterli utilizzare comodamente con le dita, ma non troppo da risultare pacchiani; in alternativa, occorre prevedere una disposizione diversa di tali controlli a seconda della dimensione del display, in modo da fornire un'interfaccia sempre adatta al contesto;
- supporto multi-touch: laddove sia intuitivo eseguire azioni con più dita, l'app deve essere in grado di rilevare questa condizione e gestirla nel modo opportuno;
- fornire un feedback immediato: è indispensabile che l'app fornisca un responso visivo o tattile immediato alle azioni dell'utente; lo stesso vale per gli spostamenti degli oggetti e per le operazioni di "pinch" e "zoom", che devono avvenire con il minor tempo di latenza possibile;
- più periferiche di input e modalità d'uso: soprattutto nel caso dei device "All-In-One", potrebbe essere necessario supportare più dispositivi di input, ad esempio gestendo le interazioni con il mouse (quando ci si trova in una configurazione desktop) oltreché quelle tramite il tocco, oppure consentire di lavorare con entrambe simultaneamente;
- ottimizzare le performance: siccome l'app può essere eseguita su dispositivi diversi, aventi dotazioni hardware eterogenee, è importante ottimizzare il codice affinché l'esperienza d'uso dell'utente non venga eccessivamente penalizzata quando l'app viene eseguita su un device con risorse limitate, magari bilanciando il raffinamento di effetti grafici e animazioni, se presenti, con un occhio di riguardo al risparmio energetico.
Piattaforme, linguaggi e strumenti
Un altro fattore cruciale per il successo della propria app è costituito dalla scelta del sistema operativo e dalle piattaforme e dispositivi che è in grado di raggiungere.
Microsoft Windows 8, ad esempio, rispetta molti dei requisiti precedentemente enunciati, fornendo un'interfaccia utente che può essere usata comodamente sia tramite mouse sia tramite touch, ed è installato all'interno di molti dispositivi, in modo particolare su Ultrabook e sistemi "All-In-One": può essere quindi una soluzione indicata per lo sviluppo di applicazioni adatte a diversi display e form factor.
Quando si parla di Windows 8, non si può non fare riferimento al marketplace che costituisce il canale privilegiato per la pubblicazione, distribuzione e acquisto delle applicazioni: Windows Store.
Il requisito per pubblicare app su Windows Store è l'adozione di linguaggi compatibili con tutte le piattaforme supportate dal marketplace, ad esempio i linguaggi standard del Web HTML5 e JavaScript. Se si utilizza Visual Studio 2013, è possibile creare progetti in grado di condividere codice e "asset" (risorse, stili, stringhe, ecc.) per generare app in grado di girare su qualsiasi device che monti un sistema operativo Windows: le cosiddette Universal Apps. Qualora si voglia invece sfruttare la propria conoscenza maturata sul linguaggio C# utilizzando il .NET Framework ed estendere la compatibilità ad altri sistemi oltre a quelli Microsoft, quali iOS e Android, è possibile ricorrere a Xamarin.
>> Scarica Educational Sample Code for Windows* 8
L'importanza della User Experience
Con il termine "User Experience" (UX) ci si riferisce alla percezione e alla risposta soggettiva degli utenti nell'uso di un determinato prodotto, sistema o servizio.
La progettazione di interfacce utente adattabili a diversi dispositivi è diventata oggi un'attività importante per il successo di un'applicazione, al punto che sono aumentate le richieste di figure professionali per curare questo aspetto, come l'UX Designer, che svolge il delicato compito di individuare le soluzioni più efficaci per fornire la migliore esperienza possibile: un'eccessiva latenza nella risposta alle azioni dell'utente, una lentezza superiore a una certa soglia tollerabile oppure la difficoltà d'uso derivante da una organizzazione farraginosa dell'interfaccia possono rendere inservisibile anche l'applicazione più interessante e ricca di funzionalità.
Per questi motivi, è importante che l'interfaccia utente sia veloce e responsiva, senza però trascurare il consumo delle risorse del dispositivo (CPU, memoria, ecc.), che nel caso di smartphone e tablet tendono a essere molto limitate, e il risparmio energetico per conservare la carica della batteria.
Gestione dell'input su diversi form factor
Per poter affrontare la problematica del supporto touch a diversi form factor con la possibilità di "degradare" verso dispositivi di input alternativi come il mouse, è necessario fare prima alcune precisazioni e definire gli elementi del dominio con cui si ha a che fare.
Innanzitutto, ci sono vari livelli di interpretazione dell'input da parte del sistema operativo, che vedremo a breve.
Windows 8 gestisce nativamente tali livelli di astrazione, ciascuno di essi adatto a un particolare contesto di utilizzo dettato dallo specifico form factor del device di riferimento, e fornisce una API che permette agli sviluppatori di fare altrettanto nelle proprie applicazioni.
I punti di contatto (Pointer)
L'API consente di ricevere eventi semplici e a basso livello, relativi a un generico "puntatore" (pointer), ossia un'entità che contiene le informazioni relative a un singolo punto di contatto del dispositivo utilizzato con lo schermo, che si tratti di un dito, o di una penna o del clic del puntatore del mouse.
A fronte del contatto, il sistema provvede a creare un oggetto Pointer
nel momento in cui viene rilevato; l'oggetto viene poi distrutto nel momento in cui cessa il contatto stesso.
In uno scenario "multi touch", ciascun punto a contatto con lo schermo rappresenta un Pointer individuale e separato.
Gesture e manipolazioni con il touch
La gestione dei Pointer fornisce le basi per l'implementazione di una gestione più complessa e articolata delle gesture e delle manipolazioni più comuni. Ad esempio, è possibile intercettare la gesture cosiddetta "tap and hold", che ha luogo quando si tocca un elemento dell'interfaccia e si lascia il dito a contatto con lo schermo, oppure quando si scorre in una direzione orizzontale o verticale - chiamata "swipe" - per sfogliare pagine sullo schermo o compiere azioni analoghe.
Quando si parla di manipolazioni, invece, ci si riferisce a una particolare interazione dell'utente con un elemento dell'interfaccia (UI) che emula in modo naturale una reale manipolazione (da qui il termine) di un elemento fisico nella realtà; ciò avviene ad esempio quando si appoggiano le dita della mano su una forma circolare per compiere una rotazione.
Esistono infine gestioni dell'input bivalenti, ovvero che funzionano sia con il tocco che con il clic, in modo da consentire all'utente di utilizzare il mouse per le operazioni di base, ad esempio quando lo schermo è collegato alla tastiera nei dispositivi "All-In-One", e di passare all'input tramite tocco sullo schermo scollegando lo schermo, per una maggiore rapidità e comodità.
>> Leggi la guida allo sviluppo per interfacce touch di dispositivi "ultra-mobile"
L'API di Windows 8
Le informazioni sui Pointer vengono veicolate attraverso l'invio di messaggi Windows (quelli identificati dalle costanti che iniziano per WM_*) alla finestra attiva dell'applicazione, oppure tramite la generazione di un evento di livello più alto nei framework che li supportano, a seconda della piattaforma di riferimento e del tipo di applicazione:
- messaggio WM_POINTER: è supportato a partire da Windows 8 per le applicazioni desktop tradizionali e può essere "catturato" per gestire sia un tocco singolo sia una gesture/manipolazione più complessa;
- messaggio WM_TOUCH: è supportato da Windows 7 (e su W8 per compatibilità all'indietro) e contiene informazioni generiche su un singolo contatto del dispositivo con lo schermo;
- messaggio WM_GESTURE: è supportato da Windows 7 e 8, e contiene informazioni relative a uno o più punti di contatto simultaneamente che costituiscono una gesture tra quelle note e supportate nativamente dall'API (pinch e zoom, swipe, slide, ecc.), a cui si possono aggiungere eventuali gesture di tipo "custom" la cui implementazione è a carico dello sviluppatore basata sulle informazioni estratte dal messaggio WM_TOUCH;
- oggetto PointerPoint: è supportato nelle applicazioni per Windows Store, indipendentemente dal linguaggio utilizzato tra quelli che supportano questa piattaforma, e viene passato come parametro dagli eventi della libreria WinRT che gestiscono i dispositivi di input; le informazioni veicolate sono analoghe a quelle dei precedenti messaggi.
Supporto a diversi form factor nel browser
Windows 8 è in grado di eseguire applicazioni basate su Internet Explorer (versione 11, al momento della scrittura di questo articolo) e implementate con i linguaggi standard del Web, ovvero HTML5, JavaScript e CSS3.
L'ambiente di esecuzione fornisce anche a questa tipologia di app tutti gli strumenti necessari sia per la fruizione in device con schermi di dimensioni diverse, sia per la gestione dell'interfaccia utente tramite diversi dispositivi di input.
A livello di interfaccia utente, l'adattamento automatico alla dimensione dello schermo può essere ottenuto adottando uno dei tanti framework disponibili, come Twitter Bootstrap ad esempio, che permettono di creare siti Web e applicazioni "responsive", organizzando i contenuti di ogni pagina dell'applicazione all'interno di una griglia che può essere ridimensionata o disposta diversamente a seconda dello spazio disponibile a video, seguendo le regole del buon Responsive Design.
La gestione dell'input standard può essere invece demandata sia ai classici gestori di evento lato client previsti dal DOM, sia a una API specifica e dedicata al supporto (multi) touch: la Pointer Events API. La specifica è ancora in fase di standardizzazione, ma può essere utilizzata per poter gestire qualsiasi tipo di interazione utente, dal tocco alle gesture, con qualsiasi dispositivo di input. E qualora l'uso dell'API risulti complesso, sono disponibili una pletora di librerie già pronte all'uso, come Touchy.js, per venirci in aiuto e semplificare lo sviluppo dell'applicazione.
Interfacce utente su più monitor
Se ritenete che supportare schermi aventi dimensioni differenti non sia sufficiente a complicare le cose, affrontiamo la possibilità giorno dopo giorno sempre più ricercata di supportare più di uno schermo (multi monitor).
Lo scenario più diffuso di questa modalità è quello del dual screen, ovvero la capacità da parte di un'applicazione di poter visualizzare contenuti su un monitor aggiuntivo (o secondario), oltreché su quello primario.
Generalmente, sullo schermo primario viene mostrata una interfaccia che consente di controllare ciò che viene visualizzato sul secondo monitor.
Ottenere le informazioni sugli schermi
Per supportare il "dual screen", la Windows API e la maggior parte dei framework forniscono agli sviluppatori classi specifiche che consentono di ottenere informazioni sul numero di monitor installati, sulle loro dimensioni e sulle caratteristiche in generale, per poter determinare quale di questi è quello primario e destinare a ciascuna periferica il relativo contenuto, posizionando le finestre nella locazione corretta.
La libreria Windows Forms, ad esempio, fornisce la classe Screen (nel namespace "System.Windows.Forms") che contiene la proprietà statica AllScreens: essa fornisce un array di oggetti Screen, uno per ogni schermo disponibile, con tutte le informazioni relative. La proprietà PrimaryScreen indica se lo schermo rappresentato dall'oggetto è quello primario, consentendone una rapida identificazione, mentre la proprietà WorkingArea di tutti gli oggetti Screen contengono l'area di lavoro dello schermo ritagliata dall'interno desktop, che viene rappresentato come la superficie virtuale ottenuta dall'unione di tutti gli schermi disponibili.
Posizionamento delle finestre sullo schermo
Tenendo presente il concetto di "working area" illustrato, la visualizzazione delle finestre su uno specifico schermo si traduce semplicemente nel posizionamento della stessa tramite la proprietà Location nelle applicazioni Windows Forms, oppure le proprietà Left e Top dell'oggetto Window se si usa WPF, per un "look&feel" moderno e una interfaccia grafica più ricca, sfruttando le potenzialità di questa libreria.
Ecco un esempio di codice che consente di posizionare la finestra di un'applicazione WPF nel display secondario e massimizzarla durante la fase di caricamento:
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
// Ricerca lo schermo impostato come secondario.
Screen secondary = null;
foreach (Screen screen in Screen.AllScreens)
{
if (!screen.Primary)
{
secondary = screen;
break;
}
}
// Se lo schermo non è stato trovato, impedisce l'apertura della finestra.
if (secondary == null)
{
MessageBox.Show("Impossibile trovare il monitor secondario");
this.Close();
return;
}
// Modifica la posizione della finestra in modo che appaia
// nell'area relativa allo schermo secondario.
Top = secondary.WorkingArea.Top;
Left = secondary.WorkingArea.Left;
// Imposta lo stato massimizzato per la finestra.
WindowState = WindowState.Maximized;
}
Gestire la modalità "a schermo intero"
Nella visualizzazione della finestra all'interno dello schermo separato, è frequente la necessità di simulare la modalità "a schermo intero", ossia rimuovendo tutte le parti della finestra non necessarie (bordo, barra del titolo e relativi pulsanti, ecc.) e coprendo tutta l'area di lavoro disponibile senza lasciare spazi inutilizzati, limitando le possibili distrazioni dell'utente.
Massimizzare la finestra può portare ad alcuni "difetti": ad esempio, accade frequentemente che la finestra allargata sbordi leggermente nell'area del desktop adiacente, o che rimangano spazi vuoti sull'area di lavoro.
Per ovviare a questo problema, occorre accertarsi sempre che il valore iniziale di WindowStyle sia impostato a "None" al momento dell'inizializzazione, o comunque che il suo stato venga impostato su "Maximize" in un secondo momento, ossia solo quando già si trova sullo schermo secondario. Per rimuovere invece i bordi, è sufficiente impostare la proprietà ResizeMode sul valore "NoResize" per inibire la visualizzazione delle classiche maniglie per il ridimensionamento.
Hardware e librerie di terze parti
Oltre alle soluzioni già prospettate, è possibile ricorrere a librerie di terze parti che semplificano il codice facendosi carico delle operazioni più tediose legate al riconoscimento e alla gestione degli schermi aggiuntivi, sfruttando funzionalità avanzate fornite dal software accoppiato ad hardware che supporta protocolli specifici, come avviene con Intel WiDi Extensions SDK, una libreria per la programmazione di macchine che supportano la tecnologia Intel WiDi, presente in moderni Ultrabook, che permette di stabilire un collegamento WiFi allo schermo del dispositivo che può essere così separato in qualsiasi momento senza interrompere la riproduzione.
Tramite questo SDK, gli sviluppatori possono integrare la tecnologia nelle proprie applicazioni, ricercare gli schermi disponibili nelle vicinanze, stabilire un collegamento ed estendere l'interfaccia utente ai display individuati.
Link utili