Cerca con Google

Translate

10 dicembre 2013

Tutorial 60 - Ridimensionamento componenti in App Inventor per adattarsi a tutte le risoluzioni schermo (smartphone e tablet)


In questo tutorial affrontiamo una possibile ottimizzazione da applicare alle nostre app create con MIT App Inventor per far si che vengano visualizzate nella miglior maniera possibile su tutti i dispositivi Android.

Come ben sapete Android è una piattaforma diffusa su una miriade di dispositivi, ed a differenza di Iphone o Windows Phone (dove esistono solo un paio di risoluzioni per tutti i dispositivi), la risoluzione e la dimensione dello schermo può variare di molto da device a device.


Se si sviluppa con l'SDK di Android ci sono molti strumenti a disposizione per lo sviluppatore per far si che la propria app venga visualizzata nel migliore dei modi su tutti i dispositivi, mentre purtroppo in App Inventor ci scontriamo con dei limiti imposti dalla "semplicità" del tool e dalla necessità di renderlo compatibile anche con le versioni più vecchie di Android (dalla 1.5 in su).

Di base infatti App Inventor lavora "sempre" ad una risoluzione nativa di 320x480px, questa è la dimensione base con cui gireranno tutte le nostre app create con questo strumento.
Se compiliamo l'apk e lo installiamo sul dispositivo, la risoluzione sarà "ancora" di 320x480px con lo sgradevole inconveniente che se la faremo girare su schermi grandi tipo quelli di un tablet da 7" o 10" l'app sarà sgranata e molto brutta da vedere.

Esiste tuttavia una soluzione parziale al problema che si compone di due passi distinti:
1 - Ridimensionare tramite procedure nel blocks editor ogni elemento della nostra app (textbox, label, canvas, sprite, etc...)
2 - Preparare il nostro apk andando a modificare AndroidManifest.xml ed inserendo il tag apposito "resize=yes" per ottimizzare la visualizzazione su display da 4" in su

L'idea di base è quella di leggere le due proprietà "Screen1.Width" e "Screen1.Height" in modo da sapere qual'è la risoluzione effettiva offerta in quel momento alla nostra app (valido solo se modifichiamo il manifest altrimenti ripeto, la risoluzione sarà sempre di 320x480px su qualsiasi dispositivo)
Confrontando questo valore con il valore "base" di larghezza x altezza (l'ormai famoso 320x480px) potremmo ricavare un fattore di scala con cui andare a riscalare tutti gli elementi della nostra app.

Per fare un esempio banale, se definiamo un canvas di dimensione 100x100px (le dimensioni in design editor vanno definite in pixel) e facciamo girare l'app su un dispositivo con risoluzione 320x480px il calcolo iniziale per il fattore scala sarà = 1, infatti come vedete qui sotto Screen1.Width sarà uguale a 320 e il risultato di 320/320 è appunto 1, quindi il nostro canvas verrà ancora visualizzato a 100x100px...


Se ora la stessa app dovesse girare su un dispositivo con risoluzione doppia (640x960) il risultato del fattore scala sarebbe = 2 e riscalando il nostro canvas di questo valore avremo ora un canvas grande 200x200px.
Dai test fatti ho visto che è meglio calcolare il fattore scala solo su una dimensione (quella orizzontale) e riscalare di questo valore sia la larghezza che l'altezza del nostro elemento per non cambiare così il rapporto di forma dell'elemento.

Riapplicando lo stesso procedimento a tutti gli elementi  della nostra app avremo la possibilità di realizzare un applicazione che si vede quasi nella stessa maniera su tutti i dispositivi Android...e sopratutto con gli elementi non sgranati, non male vero!?

Se dovete creare delle grafiche vi suggerisco di lavorare ad una risoluzione abbastanza alta (diciamo 800x1200px) e caricare queste come media in App Inventor lasciando poi il compito alla nostra procedura ed ad App2Market di riscalare le grafiche a dovere.

Vi lascio ora alla visione del video dove propongo un esempio con un canvas ed alcune label, la procedura non si discosta molto se per caso usate sprite o altri elementi della palette basic, media o animation.


Per finire vi riporto i blocchi usati nella procedura di resize:


Le impostazioni che ho usato in App2Market:


Ed il risultato con il "collage" da me creato in cui si vede l'app girare sui diversi dispositivi:

Click per visualizzare a schermo intero
Se volete scaricare il sorgente dell'app lo trovate cliccando QUA
Mentre il file apk già compilato ed ottimizzato lo trovate cliccando QUA

Ogni commento è benvenuto, se avete soluzioni migliori fatemelo sapere! :)

38 commenti:

  1. Eccellente, come tutti gli altri anche questo è un ottimo video tutorial.
    Non vedo l'ora che inizi a fare tutorial utilizzando App Inventor 2. In passato ho provato a fare qualcosa ma essendomi abituato ad AI 1 mi sono trovato un po spaesato. Spero come dici tu alla fine del tutorial di imparare presto e riuscirmi a districare come in AI 1.
    Naturalmente con il tuo aiuto e con i tuoi tutorial sono sicuro che mi troverò benissimo anche con la nuova versione.
    Grazie di tutto ciò che fai per noi. A presto .....

    RispondiElimina
    Risposte
    1. grazie Gianluca, tranquillo che con AI2 ci si abitua in fretta, anch'io sono ancora un pò spaesato ed imparerò insieme a voi,
      voglio ripartire dall'inizio per avvicinare così anche nuovi programmatori in erba a questo fantastico mondo.
      Continua a seguirmi e vedrai che il passaggio ad AI2 sarà quasi indolore :)

      Elimina
  2. Ciao, inanzitutto complimenti per l tuo fantastico lavoro con i tutorial di app inventor! Volevo un chiarimento riguardo AI2 : dove trovo le "definition" del blocks editor? Grazie in anticipo :-)

    RispondiElimina
    Risposte
    1. se ho capito bene vuoi creare delle variabili giusto?
      Le crei da variables con "initialize global name to" trascini e poi cambi "name" nel nome della tua var,
      qui uno screen d'esempio:
      http://i.imgur.com/OHqxYuz.png

      Elimina
  3. Ti volevo solo informare che la mia procedura e simile ma diversa, Con alcuni punti in comune, tipo il problema del font size dei button, e tu consigli di usare immagini, ma si puo anche usare un canvas come button e li trovi il Canvas.FontSIze, per chi non vuole fare immagini.

    io a differenza tua uso:
    set tutti i vari Width to (Width/360)*Screen.Width
    set tutti i vari Height to (Height/615)*Screen.Height
    615 perche con appToMarket uso Screen NoTitleBar

    Differenze:
    Io setto Min SDK Ver a 7 perche sono ancora in commercio telefoni con android 2.1 ( il 9 e 2.3 ) e target a 11 ( da tuo consiglio in un altro tutorial)
    Il resizable to NO ( perche con le mie impostazioni non fa differenza )
    e non vado a fare il Edit Manifest inserendo x-large ( 1 perche non mi funziona mi da errore, 2 perche funziona ugualmente, su google play APK Details in screen layouts mi porta i 4 screen, small, normal, large, xlarge )
    E per le grafiche 800x1367, 1367 sempre perche uso appToMarket con Screen NoTitleBar

    E ti devo ringraziare perche grazie al tuo tutorial mi sono ricordato dell'esistenza di Advanced Any..... che fin ora non usavo e usavo la formula per tutti i vari Arrangement, Image, Canvas, Lable etc quindi veniva un codice lunghissimo.

    Dimenticavo la formula in alto serve per screen in Portrail, in Landscape si devono invertire i valori.

    RispondiElimina
    Risposte
    1. Grazie Benedetto!
      in effetti le mie considerazioni sono state fatte pensando ad un app "classica" con titlebar e statusbar, se invece queste vengono tolte si può dare delle dimensioni leggermente superiori da valutare appunto di volta in volta.
      Per la risoluzione "base" di 320x480 mi sono basato su quello che è l'output di screen1.width e height quando si fa girare l'app su emulatore, di fatto come detto nel video preferisco usare un unico fattore di scala per non "distorcere" le immagini su schermi che sono spesso più alti o più bassi a seconda del device e non calcolare quindi anche la scala su y ma solo su x...

      E' vero la min SDK forse sarebbe meglio metterla a 7 per prendere un pò più di devices, forse però mettendola a 7 ti esce l'errore con il tag Xlargescreen che dovrebbe essere supportato dalla 9 in poi...

      insomma c'è un bel pò di materiale su cui studiare e sperimentare, ovviamente l'argomento è parecchio complesso e non era possibile coprire tutto al 100% in 20min di video

      cmq grazie ancora per i tuoi suggerimenti e consigli :)

      Elimina
  4. Interessante ma... a questo punto perché non proporre al MIT la possibilità universale di inserire i vari componenti con dimensioni espresse in percentuale? Unica soluzione per un sistema aperto a varie tipologie di schermi.
    Sebastiano ci pensi tu?
    ;)

    RispondiElimina
    Risposte
    1. ci sono già molte "feature request" che chiedono di poter lavorare anche su app per tablet e per schermi con diverse risoluzioni,
      quindi di sicuro il MIT è al corrente di questa limitazione e stanno studiando qualcosa,
      la cosa migliore sarebbe quello di specificare le dimensioni in DP (density pixel) e non in pixel, in modo da averle già riscalate automaticamente per ogni risoluzione possibile,
      vedremo cosa accadrà, per ora questa è una possibile soluzione, per il resto bisogna attendere... :)

      Elimina
  5. Ciao Sebastiano io ho da poco iniziato a seguire i tuoi tutorial e sto usando AI2.. Avevo in mente di creare un app con qualche immagine per poi impostarla come sfondo... Come faccio a creare quel pulsante x impostare un immagine come sfondo?? Solo tu puoi aiutarmi

    RispondiElimina
    Risposte
    1. Scusami non son sicuro di aver capito, vuoi impostare un immagine dalla tua app allo sfondo del telefono (insomma vuoi impostare un wallpaper usando un app creata con AI2?) se questo è il quesito la risposta è che non si può fare...
      Però è molto semplice fare un app del genere in Eclipse ad esempio, usando Android SDK (avevo anche trovato dei tutorial su YT sul come fare)
      se invece ho capito male, cerca di spiegarti meglio :) ciao

      Elimina
    2. Si grazie era proprio quella la domanda. Ora sto cercando qualche tutorial ma non riesco a trovarlo.

      Elimina
    3. questo è in inglese:
      http://www.mybringback.com/tutorial-series/674/android-the-basics-21-setting-up-xml-for-wallpaper-app/
      se segui anche i suoi tutorial precedenti puoi imparare molto delle basi di eclipse e java

      Elimina
  6. Scusa se ti disturbo ma vorrei farti una domanda, e possibile con app inventor 2 gestire il tasto fisico di sinistra, per aprire degli schermi.

    ciao

    RispondiElimina
    Risposte
    1. non tutti i telefoni hanno un tasto fisico...tantopiù a sinistra...
      ogni produttore ha il suo posizionamento dei tasti,
      cmq se intendi il tasto "back" si lo puoi gestire con l'evento apposito "back pressed"
      se invece intendi il tasto "menù" quello non si può gestire con la versione di AI2 o AI gratuita (ovvero quella del MIT)
      esistono però le versioni di Hossein a di Jose (a pagamento) che permettono la programmazione del tasto menù, se sei interessato nel forum trovi maggiori informazioni,
      ciao

      Elimina
  7. Scusa Seba ,come funzionano le procedure in ai2 , io sto tentando di ridimensionare i componenti ma le procedures sono diverse non permettono di creare ad esempio il canvas name per tutti i canvas.

    RispondiElimina
    Risposte
    1. spero di poter pubblicare presto lo stesso tutorial in versione AI2

      Elimina
  8. Ciao Seba!
    Ho seguito questo tutorial sul resize.
    Testato con resize img (320x420) su S4 ed è OK.
    Mentre su un altro dispositivo con risoluzione 320x350.... non va bene...tutto "appiccicato"!
    Non sarebbe meglio,quindi, calcolare il fattore scala anche x la dim verticale ?

    RispondiElimina
    Risposte
    1. Ciao Alessandro, puoi anche farlo ma da quello che avevo visto io non avevo senso calcolare anche il fattore di scala verticale perchè perdevi il rapporto altezza/lunghezza e le grafiche venivano stiracchiate,
      prova ad inserirlo e magari mi fai sapere così posso migliorare il mio tutorial,
      ci sentiamo presto, ciao

      Elimina
    2. Ciao Alessandro e Sebastiano,
      mi permetto di proporre una idea che potrebbe essere la soluzione al problema posto da Alessandro.
      Per migliorare i rapporti tra i componenti delle mie schermate io inserisco delle label vuote. Quando applico gli esempi di Sebastiano ai miei progetti, ridimensiono come scritto gli oggetti "visibili" in modo da conservarne i rapporti delle dimensioni (per non stiracchiare tutto) e ridimensiono anche (sempre con la stessa tecnica) le label vuote che uso come distanziatori...et voilà...
      Spero di essere stato chiaro e che la mia soluzione sia valida anche per Alessandro e tutti gli alti che si sono posti lo stesso problema.
      A presto

      Elimina
  9. Ciao Sebastiano, tutorial molto utile. Io però ho notato che se ad esempio l'app imposta lo schermo in verticale (portrait) e mentre parte il dispositivo è orizzontale, sorgono alcuni problemi. Infatti il dispositivo per rendere verticale lo screen ci mette un po' e quindi la app prende per larghezza quello che in effetti è l'altezza e viceversa. Io ho aggiunto quindi una serie di if che vanno a confrontare i valori di width e height ed eventualmente switciare i valori a seconda che la app funzioni in verticale (portrait) o orizzontale (landscape).

    RispondiElimina
    Risposte
    1. Hai fatto benissimo, anch'io avevo notato questa cosa ma il tutorial sarebbe diventato troppo "noioso" e come tutti i miei tutorial questi vogliono solo essere uno spunto e/o una base di partenza per poi realizzare le app "finite" dove lascio al lettore il compito di perfezionare e testare tutti gli aspetti di esse.
      Grazie per la segnalazione, servirà di sicuro a qualcuno che leggerà questo tuo commento :)

      Elimina
  10. Ciao Sebastiano, non so dove postare la domanda, e la metto qui scusa se è nel posto sbagliato.
    Mi serviva sapere se attualmente si possono creare app in background su app inventor, magari con quelle a pagamento di Hossein a di Jose.
    ciao Igor

    RispondiElimina
    Risposte
    1. Che sappia io non è ancora possibile,

      cmq per questo genere di domande esiste il forum :)

      Elimina
  11. Ciao, io ho seguito tutte le tue direttive per il ridimensionamento dell'app anche per i tablet e devo dire che funziona abbastanza bene,i problemi sorgono quando passo l'app originale su AppToMarket perchè questi riporta l'app allo stato originario annullando tutte le modifiche di resize,non capisco perchè,ho sperimentato tutti i settaggi possibili ma niente

    RispondiElimina
  12. Ciao a tutti, ciao Sebastiano.
    Ho notato che se uso un resize (di qualsiasi tipo) ad un oggetto nascosto che poi deve apparire tramite un comando, non funziona correttamente. Mi spiego meglio. Supponiamo di avere 2 Button (on e off) e voglio che quando premo il primo, questi scompaia per fare apparire l'altro e viceversa. Tutto è facilmente gestibile dalla funzione visible (true/false) ma se provo ad inserire un cambio di dimensione (sia seguendo il tuo ottimo tutorial, sia banalmente settando una nuova dimensione) il secondo pulsante, quello che nella prima fase è nascosto, non apparirà,. Non inserendo nessun tipo di variazione di dimensione, tutto funziona correttamente... Qualche idea?.
    Salute e saluti a tutti :)
    Maurizio
    PS. Ne ho scritto anche sul forum di appinventor.

    RispondiElimina
    Risposte
    1. Ciao, onestamente non ho mai provato questa cosa, hai provato a vedere se con le nuove versioni e con l'opzione responsive per lo zoom fa la stessa cosa?
      Ma se fissi le dimensioni che ne so da design editor, il problema accade?
      Oppure prova a settarle anche da blocks editor e prova a mettere un pulsante di debug che ti faccia il ridimensionamento forzato, mi spiego: crea la tua app come hai detto tu.
      Poi aggiungi un ulteriore button che quando viene premuto imposta height e width dell'altro button che era nascosto alle dimensioni desiderate.
      Non vorrei fosse un semplice errore di ordine con cui esegui le operazioni, magari rendi prima visibile il componente e solo dopo ne imposti le dimensioni...
      spero di averti dato qualche dritta utile, fammi sapere! ciao!

      Elimina
    2. Questo commento è stato eliminato dall'autore.

      Elimina
    3. Ho eliminato il commento precedente perchè nel frattempo ho risolto. Spiego come, per chi avesse lo stesso problema. In effetti (come hai suggerito) è questione di ordine delle operazioni. Ma non dipendeva da me perchè il rescaling era impostato nello screen initialize. Allora sono partito dal design editor con l'oggetto che deve essere nascosto impostato in realtà su visibile e poi lo ho impostato su visible/false nello screen initialize. Così ha funzionato. Unica pecca, si intravedono i due oggetti all'inizio. Ultima cosa "opzione responsive per lo zoom" dove la trovo?
      Grazie Sebastiano: sei prezioso.

      Elimina
    4. Infatti, è come pensavo io. Secondo me potresti anche provare con un timer o un qualcosa che ti faccia il ridimensionamento qualche millisecondo dopo lo screen initialize e magari risolvi.
      Dovresti fare varie prove per capire dove è meglio mettere il resize.
      Oppure lo puoi anche provare a mettere subito prima di far diventare visibile di nuovo il button, io credo che così funzionerà.
      Prova e fammi sapere

      Elimina
  13. No, mi dispiace non è possibile, non dipende dal componente webviewer ma dalla pagina html stessa.
    Per esempio io ho cambiato la pagina html che viene caricata nella mia pagina per far si che avesse uno zoom "corretto" per le immagini, devi quindi lavorare lato html e non lato app in AI.
    Spero di esserti stato d'aiuto! ciao!

    RispondiElimina
  14. Ciao Seb...complimenti per i tuoi Tutorial sempre molto efficaci, tuttavia questa volta hai lasciato un dubbio :) Scherzo, ma la domanda nasce spontanea..Basta fare il resize sullo screen1 o bisogna ripeterlo per ogni screen. E poi con questa procedura google riconosce la app anche per tablet??
    Grazie anticipatamente per le tue risposte.
    Antonello

    RispondiElimina
    Risposte
    1. Ciao Antonello! grazie per i complimenti!
      Il resize va fatto ovviamente su tutti gli screen, o almeno su quelli dove vuoi che ci sia il ridimensionamento delle immagini.
      Considera che da qualche versione di AI c'è la modalita "responsive" per cui almeno per i testi i pulsanti e tutto quello che non è nella palette "drawing and animation" il resize viene fatto automaticamente.

      Google play store continuerà però a dire che l'app non è ottimizzata per tablet, perchè per come è strutturato AI mancano delle risorse che vengono controllate dal Play Store, quindi il messaggio resta ma l'app è comunque installabile su tablet.

      Elimina
    2. E' anche appena uscito un interessante articolo sulla gestione delle immagini in App Inventor, ti consiglio di darci una letta è veramente fatto bene e molto interessante (ed anche molto aggiornato)...

      http://ai2.appinventor.mit.edu/reference/other/usingImages.html

      Elimina
  15. Ciao, ho letto il tuo chiarissimo tutorial (grazie!!) ma a me non funziona!
    Utilizzo MIT AppInventor 2, AppToMarket 4.1 ma nonostante imposti a YES la voce "resizable", andando nell'editor rimane a False: anche mettendo True il risultato non cambia..
    Vist che è passato un po' di tempo dalla pubblicazione del tutorial, hai qualche idea?
    Grazie anticipate.

    RispondiElimina
  16. Ciao Seb, ho iniziato da poco ad addentrarmi in questo mondo.
    Ho letto alcuni tuoi tutorial, peccato che il progetto sia fermo da anni, avrei tante cose da chiedere e capire.

    RispondiElimina
    Risposte
    1. Hey, mi fa piacere sapere che questo blog viene ancora letto da qualcuno interessato al progetto.
      "Purtroppo" eventi della vita mi hanno portato a dedicarmi ad altro al momento e quindi come vedi il progetto è sospeso da tempo.
      Spero cmq che questi articoli possano dare una buona base a chi come te sia interessato al mondo di App Inventor! buona fortuna!

      Elimina
    2. Grazie, ci proverò.
      Ma dal momento che mi rispondi vorrei chiederti una cosa.
      Vedo che questo Tutorial è basato su App Invertor 1 e si può scaricare la sorgente dell'app.
      Purtroppo non riesco, guardando il tutorial, ad adattare le procedure ad App Inventor 2.
      E scaricando il file sorgente non so come importarlo in AI2 che chiede dei files .aia.

      Mi sapresti dire come importare questo file sorgente in AI2?
      Grazie

      Elimina