PhoneGap Android SplashScreen

HelloSplash, Phonegap Android SplashScreen

Come in un primo incontro tra due estranei, un aspetto cruciale delle applicazioni mobile quando incontrano i nostri nuovi utenti, che lo si voglia ammettere o no, è la prima impressione.

Lo splash screen è la primissima cosa che gli utenti hanno a disposizione per giudicare un’app la prima volta che la aprono, il modo in cui lo mescoliamo con la nostra UI, possibilmente dotandolo di un ruolo funzionale, può incrementare notevolmente la qualità percepita dell’applicazione, se fatto male può ottenere anche l’effetto opposto.

Notare bene che le seguenti operazioni sono eseguite con PhoneGap versione 3.3.0, quindi le istruzioni sono valide dalla versione 3 in su.

Cordova Hello World avvio applicazione

La prima cosa che ho fatto è stato creare un progetto Hello World, che ho nominato HelloSplash su GitHub, per verificare come lo splash screen viene gestito, presumendo che un aspetto tanto richiesto come questo fosse abilitato di fabbrica, quindi buildo il progetto e lo lancio in un emulatore Android 2.3 (HelloSplash tag v1.0.0).

Tutt’altro che gradevole, una schermata nera che dura fintanto che la UI dell’app compare di scatto non è la migliore delle presentazioni.

Cercando della documentazione su come gestire lo splash screen mi sono imbattuto nel tutorial ufficiale del plugin SplashScreen.

Dopo aver seguito tutte le istruzioni ho creato una immagine di prova nelle quattro risoluzioni richieste, un metodo per generarle velocemente è impostare il documento a partire dalla versione XHDPI, così da generare le risoluzioni più basse attraverso il downsampling in fase di esportazione, tenendo presente le seguenti proporzioni :

  • LDPI : 38%
  • MDPI: 50%
  • HDPI: 75%
  • XHDPI: 100%

Ora che abbiamo tutte le immagini le possiamo inserire nelle cartelle appropriate che nel nostro caso sono :

Re-buildiamo l’app, e non è cambiato niente…perché? Abbiamo seguito tutte le istruzioni della documentazione ufficiale, ma c’è qualcosa che non va nella seguente riga :

In config.xml in the project’s www directory, add the following preferences

Il fatto è che dentro il nostro progetto ci sono tre files config.xml :

L’unico che verrà effettivamente letto ed eseguito da Android è ovviamente l’ultimo che viene compilato in fase di build, nella documentazione ci dicono di modificare il secondo perchè pensano sia quello che verrà usato in fase di build per aggiornare il terzo compilato ma viene completamente ignorato, quello che viene effettivamente incluso è il primo, quindi il file giusto da modificare per aggiornare anche il compilato è quello nella root hellosplash/HelloSplash/config.xml con i seguenti parametri:

hellosplash-officialdocs
Lo splash screen del plugin appare a metà avvio

Re-buildiamo l’app e adesso abbiamo uno splash screen, tuttavia abbiamo ancora anche la schermata nera iniziale.
(HelloSplash tag v1.1.0)

Inoltre si nota chiaramente come l’immagine abbia una dissolvenza in entrata ma non in uscita, anche se chiamassimo direttamente il metodo navigator.splashscreen.hide() la schermata sparirebbe di colpo, presentando la nostra UI in maniera abbastanza bruta.

Sfortunatamente il plugin non mette a disposizione alcun metodo per modificare questi aspetti. Se vogliamo conferire allo splash screen un aspetto più “professionale” e meno grezzo dovremo sporcarci le mani al di fuori della cartella www.

Fasi di avvio di un’app PhoneGap su Android

Per capire come risolvere il problema dobbiamo comprendere il flusso e i passi che compongono l’avvio di un’applicazione, si tratta di un processo composto da cinque fasi, ciascuna delle quali mostra all’utente una schermata diversa, in rapida successione :

  1. Finestra dell’applicazione Android
  2. Finestra dell’attività in dissolvenza
  3. WebView inizializzata
  4. Pagina HTML risorse in fase di caricamento, schermata bianca
  5. Pagina HTML caricata, risorse CSS e JS caricate ed eseguite

Prima di passare ad occuparci di questi punti conviene dare una sbirciata alla documentazione ufficiale dei temi nativi Android, nulla di cui aver paura.

Cambiare lo sfondo della finestra di applicazione Android con un tema-figlio nativo

La prima schermata nera è lo sfondo della finestra dell’applicazione, il contenitore nativo Java vuoto che racchiude la nostra web app, ed il colore che vediamo proviene dal tema nativo assegnato all’applicazione.

Ogni progetto PhoneGap che generiamo è prodotto con un tema predefinito dichiarato nel file AndroidManifest.xml, situato come ultimo attributo del tag activity :

La nostra app è composta da un’unica attività che utilizza il tema Theme.Black.NoTitleBar.

Per sovrascrivere solo alcuni aspetti di un tema per adattarli alle nostre necessità dobbiamo creare un tema figlio che referenzi quello già in uno come tema padre ridefinendo gli elementi che vogliamo modificare, basilarmente sovrascrivendoli come faremmo con la specificità CSS.

La documentazione specifica che il nome del file che memorizza i nostri stili è arbitrario, ma per semplicità ed evitare confusione consiglio di nominarlo style.xml, qui di seguito il percorso completo, userò lo stesso colore presente nell’immagine di prova:

Ora per consentire alla nostra app di usare questo tema invece di quello predefinito nel file AndroidManifest.xml dobbiamo modificare l’ultimo attributo del tag activity da:

a

Notare come dopo la chiocciola ometto di scrivere “android:” perchè non sto più facendo riferimento ad un tema globale incluso di frabbrica nel sistema, ma punto ad un mio tema memorizzato nel file style.xml.

Prevenire il lampeggiamento della WebView HTML con un ritardo della dissolvenza

Android PhoneGap app startup five phases
Tutte le cinque fasi che attraversa l’applicazione all’avvio

Se commentiamo le ultime due righe che abbiamo appena aggiunto nel file config.xml per disattivare temporaneamente il plugin dello splash screen vedremo chiaramente tutte le fasi elencate in precedenza.

Notiamo che il primo colore che ci accoglie non è più il nero ma l’esadecimale che abbia impostato nel nostro tema personalizzato, inoltre ci accorgiamo che la dissolvenza della schermata non era relativa allo splash screen, è la finestra dell’attività stessa che appare in dissolvenza all’interno della finestra dell’applicazione, che fin dall’inizio mostra l’immagine splash screen che abbiamo configurato nel file config.xml.

Ma notiamo altri due effetti, dopo la dissolvenza dell’attività segue un rapido lampeggiamento nero e bianco ed infine la pagina HTML appare, ciò che si verifica è che la WebView viene inizializzata dentro la finestra dell’attività, inizia il caricamento delle risorse statiche impacchettate nell’app mostrando quindi una pagina HTML bianca, infine quando le risorse sono state caricate ed eseguite appare la pagina renderizzata.

Questi passaggi, elencati prima dal 3 al 5, erano mascherati dalla presenza della schermata dello splash screen che ricopriva tutta l’area visibile dell’attività mentre tutte le operazioni erano in corso, non avendo inserito una callback nel nostro JavaScript per far sparire la schermata questa si protrae per tutta la durata impostata nel parametro SplashScreenDelay, al termine della quale la pagina è già stata renderizzata.

Come suggerito nella documentazione ufficiale, non dobbiamo lasciare lo splash screen per un tempo troppo lungo ma rimuoverlo appena la nostra UI è disponibile, ovvero in corrispondenza dell’evento document ready.

Tuttavia se nascondiamo la schermata in corrispondenza di tale evento può accadere che sia ancora presente per pochi instanti la schermata nera di inizializzazione prima che la pagina HTML renderizzata appaia, dopo diverse prove ho appurato che un ritardo di 1,5 secondi successivamente all’evento document ready è sufficiente per assicurarsi che la pagina sotto la schermata sia effettivamente visibile. Quindi aggiungiamo le seguenti righe nella funzione receivedEvent del file www/index.js :

Quando lo splash screen si nasconderà avremo la nostra pagina pronta, tuttavia la schermata sparisce senza dissolvenza e non è molto elegante, ma arrivati a questo punto siamo nel campo tecnologico del web, abbiamo tutto il controllo necessario per gestire la situazione 🙂 .

Controfigura HTML per la dissolvenza dello splash screen

Il primo elemento che serve nella pagina HTML è un div che abbia come immagine di sfondo quella utilizzata nel plugin, in modo che quando nascondiamo la schermata non si noti nessun cambiamento perchè si continua a vedere la stessa immagine, con la differenza che possiamo applicare qualsiasi effetto di dissolvenza essendo un elemento HTML.

Copiamo l’immagine drawable-xhdpi/splash.png nella cartella www/img/ in modo che sia accessibile via CSS, ora nel file index.html inseriamo come primo figlio del body il seguente :

ed applichiamo i seguenti stili:

adesso nella funzione di timeout che avevamo creato aggiungiamo anche la dissolvenza in uscita fadeOut del div :

hellosplash-colortofade
Avvio con colore personalizzato, dissolvenza dello splash screen combaciante, dissolvenza della replica HTML

Ora l’applicazione si avvia con un colore a nostra scelta, che combacia con quello dell’immagine in dissolvenza da noi impostata, la quale si nasconde a sua volta in dissolvenza arrivati alla parte HTML rivelando la nostra app.
(HelloSplash tag v1.2.0)

Quasi quello che volevamo, hai notato un problema vero?

Il rapporto di forma delle due immagini è diverso, il problema è che stiamo usando un set di immagini pensato per essere deliberatamente più grande dello schermo in modo da ricoprire tutta l’area visibile, ma su Android ogni elemento della UI che mostra come sfondo un immagine se non istruito su come trattarla la allargherà per contenerla nel proprio riquadro, nel caso delle immagini 9-patch suggerite nella documentazione verrebbero allargate solo le parti preposte lasciando il centro dell’immagine inalterato.

Ho provato diverse volte ad ottenere delle immagini 9-patch funzionanti, anche con programmi di terze parti, ma senza successo, e se volessimo usare degli elementi grafici più complessi rispetto ad un singolo colore solido con un immagine centrata, come ad esempio dei gradienti o una foto, non sarebbe comunque lo strumento migliore.

Il prossimo passo è quindi gestire il dimensionamento delle immagini.

XML bitmap per i metadati delle immagini

Per indicare alla schermata dello splash screen di non modificare il rapporto di forma dell’immagine e tenerla invece centrata sullo schermo possiamo usare i file XML bitmat per specificare le informazioni di gestione delle nostre immagini.

Dobbiamo aggiornare in ogni cartella drawable-* i nomi delle immagini poiché non possono combaciare con i nomi degli XML anche avendo estensioni diverse, inoltre dato che i nomi vengono memorizzati dal compilatore in fase di build per creare dei resource ID per non incorrere in errori conviene usare un nome diverso anche per i nuovi files XML :

Tutti i files XML devono avere lo stesso contenuto, nel quale specifichiamo di non allargare l’immagini e ne specifichiamo il percorso, che risiedendo nella stessa cartella dell’XML si esaurisce nel solo nome del file png :

Ora che abbiamo cambiato i nomi dei file dobbiamo aggiornare anche il file di root config.xml per fargli recuperare i nostri files XML, che diranno al sistema a quali immagini puntare e come gestirle :

Ora che l’immagine non viene più distorta modifichiamo anche la proprietà CSS background-size della nostra controfigura HTML :

HelloSplash tag v1.3.0

hellosplash-xmlbitmap
Risultato finale con tutti i passaggi applicati

Riepilogo, personalizzare callbacks ed effetti

Rivediamo tutti i passi salienti per gestire ciascuna fase del processo di avvio :

  1. Per cambiare il colore di sfondo predefinito della finestra dell’applicazione creiamo un tema-figlio nativo in style.xml e aggiorniamo il file AndroidManifest.xml
  2. Abilitiamo il plugin SlashScreen di PhoneGap aggiungendo i due parametri, durata e percorso, nel config.xml nella root del progetto. Il percorso deve puntare al nome dei file XML bitmap che creeremo per modificare la gestione delle nostre immagini che risiederanno insieme agli XML stessi in ogni cartella drawable-*.
  3. Nel file index.js invochiamo il metodo hide del plugin per nascondere lo splash screen 1,5 secondi dopo l’evento document ready per assicurarci che la pagina HTML sottostante sia stata effettivamente renderizzata, allo stesso tempo effettueremo la dissolvenza della replica HTML dello splash screen nativo per mostrare elegantemente la nostra web app.
phonegap-android-splashscreen-infographic
Infografica delle fasi di avvio di un Applicazione PhoneGap su Android e dei metodi per personalizzarle

Per quanto riguarda i tempi in base ai quali nascondere la schermata di splash screen ho usato l’evento document ready solo come esempio.

Se l’app deve recuperare dei dati, dal web o da un database interno, o serve del tempo per attendere l’avvio di altri servizi accessori prima che la UI dell’app possa essere renderizzata, si può invocare le funzioni di hidefadeOut in un momento successivo in occorrenza dell’evento corretto.

Inoltre si può personalizzare la dissolvenza della replica HTML dello splash screen in qualunque modo, si può adesempio imitare l’animazione di spring out tipica della chiusura delle app con una combinazione di CSS3 animando la proprietà transform scale da 1 a 0.7 insieme all’opacità da 1 a 0

oppure l’esatto contrario, con un effetto di spring in della UI dell’app, che si posiziona sopra lo splash screen HTML

la scelta spetta a te 🙂 .

https://sresc.io/p

2 thoughts on “HelloSplash, Phonegap Android SplashScreen”

Lascia un commento

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.