{"id":11495,"date":"2015-12-02T17:05:13","date_gmt":"2015-12-02T16:05:13","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=11495"},"modified":"2016-06-07T14:55:02","modified_gmt":"2016-06-07T12:55:02","slug":"tutorial-android-percent-support-library-per-il-layout-delle-nostre-applicazioni-android","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/tutorial-android-percent-support-library-per-il-layout-delle-nostre-applicazioni-android\/","title":{"rendered":"Tutorial: Android Percent Support Library per il layout delle nostre applicazioni Android"},"content":{"rendered":"<p>La libreria di supporto del sistema Android \u00e8 stata recentemente arricchita di un nuovo ramo, la <strong>Percent Support Library<\/strong>, che l&#8217;ha dotata di\u00a0un qualcosa che \u00e8 sempre stato\u00a0richiesto a gran voce: il\u00a0dimensionamento delle componenti visuali in percentuale nelle applicazioni Android, proprio come si \u00e8 abituati a fare nei layout web.<\/p>\n<p>In questo articolo, vedremo la novit\u00e0 al lavoro in un esempio pratico, ma per poterla gustare al meglio facciamo prima un p\u00f2 di preambolo.<\/p>\n<h2>Un p\u00f2 di <em>background<\/em>: layout e dimensioni<\/h2>\n<p>Quando progettiamo un&#8217;interfaccia utente in un&#8217;app Android sappiamo che la prima cosa da fare \u00e8 scegliere quale layout le si addice meglio. Un layout &#8211; tanto per ricordare il concetto &#8211; \u00e8 il modo in cui viene gestita la disposizione fisica degli elementi visuali. I pi\u00f9 comuni ma non gli unici \u00a0che esistono nello sviluppo Android sono:<\/p>\n<ul>\n<li>il <strong>LinearLayout<\/strong> che dispone gli elementi &#8220;linearmente&#8221;, da sinistra a destra o dall&#8217;alto in basso a seconda che\u00a0abbia un orientamento orizzontale o verticale;<\/li>\n<li>il <strong>RelativeLayout<\/strong>, il pi\u00f9 flessibile, rende ogni elemento &#8220;flottante&#8221; e non ci resta che\u00a0stabilire i rapporti di posizionamento tra il singolo elemento ed il suo contenitore o tra un elemento e l&#8217;altro;<\/li>\n<li>il <strong>FrameLayout <\/strong>destinato a contenere un singolo componente, spesso\u00a0il segnaposto di un <em>Fragment<\/em>.<\/li>\n<\/ul>\n<p>Ci\u00f2\u00a0che accomuna tutti gli elementi grafici in Android &#8211; siano essi layout che altri tipi di View &#8211; sono i parametri <em>layout_width<\/em> e <em>layout_height<\/em> che, rispettivamente, definiscono il modo in cui un componente si estende in\u00a0larghezza e altezza. Tali dimensioni vanno espresse possibilmente con le costanti <em>wrap_content<\/em> e <em>match_parent<\/em> o, quando necessario, con delle dimensioni esplicite in dp, il pixel &#8220;virtuale&#8221; che si adatta alla densit\u00e0 dello schermo.<\/p>\n<p>Ci\u00f2 che mancava\u00a0era un dimensionamento &#8220;ufficiale&#8221; in percentuale ossia la possibilit\u00e0 di dichiarare:\u00a0&#8220;questo elemento deve essere largo il 30% del suo contenitore&#8221;. In alternativa, si poteva fare qualcosa di simile con l&#8217;attributo <em>layout_weight<\/em> che assegnava un peso agli elementi o con un dimensionamento dinamico in Java.<\/p>\n<p>Per sopperire a questa necessit\u00e0, come detto nell&#8217;introduzione, \u00e8 stata integrata la libreria di supporto con il ramo Percent il quale\u00a0ha portato con s\u00e8 due nuovi layout, <strong>PercentRelativeLayout<\/strong> e <strong>PercentFrameLayout<\/strong>, nonch\u00e8 gli strumenti necessari per crearne di propri.<\/p>\n<h2>Integrare la Percent Support Library<\/h2>\n<p>Aggiungerla al proprio progetto Android Studio \u00e8 molto agevole\u00a0grazie a Gradle. E&#8217; sufficiente inserire\u00a0nel nodo dependencies del file build.gradle del modulo la seguente riga:<\/p>\n<pre class=\"lang:java decode:true \">com.android.support:percent:23.1.0<\/pre>\n<p>senza dimenticarsi di sincronizzare il progetto con il pulsante &#8220;Sync Project with Gradle Files&#8221; <a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidstudio_syncprojectwithgradle.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11499\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidstudio_syncprojectwithgradle.jpg\" alt=\"androidstudio_syncprojectwithgradle\" width=\"23\" height=\"27\" \/><\/a>.<\/p>\n<p>Quando Gradle avr\u00e0 terminato il suo lavoro di aggiornamento le nuove funzionalit\u00e0 saranno disponibili.<\/p>\n<h2>L&#8217;esempio<\/h2>\n<p>L&#8217;esempio che tratteremo sar\u00e0 molto semplice ma mostrer\u00e0 rapidamente in cosa consiste la novit\u00e0.<\/p>\n<p>La figura seguente mostra un&#8217;interfaccia piuttosto elementare in cui due TextView indicano la larghezza e l&#8217;altezza in pixel del display (misurate con quanto offre la classe <em>DisplayMetrics<\/em>) e due pulsanti modellati con le nuove dimensioni in percentuale: uno largo il 50% del contenitore ed uno l&#8217;80.<br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11510\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_01.jpg\" alt=\"androidpercentsupportlibrary_01\" width=\"480\" height=\"411\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_01.jpg 480w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_01-300x257.jpg 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Questo il layout formattato in XML:<\/p>\n<pre class=\"lang:xhtml decode:true\">&lt;android.support.percent.PercentRelativeLayout\r\n        xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n        xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\r\n        xmlns:tools=\"http:\/\/schemas.android.com\/tools\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:paddingBottom=\"@dimen\/activity_vertical_margin\"\r\n        android:paddingLeft=\"@dimen\/activity_horizontal_margin\"\r\n        android:paddingRight=\"@dimen\/activity_horizontal_margin\"\r\n        android:paddingTop=\"@dimen\/activity_vertical_margin\"\r\n        app:layout_behavior=\"@string\/appbar_scrolling_view_behavior\"\r\n        tools:context=\".MainActivity\"&gt;\r\n\r\n        &lt;TableLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:id=\"@+id\/dimensioni\"&gt;\r\n            &lt;TableRow&gt;\r\n                &lt;TextView\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_weight=\"1\"\r\n                    android:text=\"Larghezza (pixel)\"\/&gt;\r\n                &lt;TextView\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_weight=\"1\"\r\n                    android:id=\"@+id\/txt_larghezzapx\"\/&gt;\r\n            &lt;\/TableRow&gt;\r\n            &lt;TableRow&gt;\r\n                &lt;TextView\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_weight=\"1\"\r\n                    android:text=\"Altezza (pixel)\"\/&gt;\r\n                &lt;TextView\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_weight=\"1\"\r\n                    android:id=\"@+id\/txt_altezzapx\"\/&gt;\r\n            &lt;\/TableRow&gt;\r\n\r\n        &lt;\/TableLayout&gt;\r\n\r\n        &lt;Button\r\n            app:layout_widthPercent=\"50%\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:text=\"Larghezza 50%\"\r\n            android:layout_centerHorizontal=\"true\"\r\n            android:layout_below=\"@id\/dimensioni\"\r\n            android:layout_marginTop=\"20dp\"\r\n            android:id=\"@+id\/button50\"\r\n            android:onClick=\"showDimension\"\/&gt;\r\n\r\n        &lt;Button\r\n            app:layout_widthPercent=\"80%\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:text=\"Larghezza 80%\"\r\n            android:layout_centerHorizontal=\"true\"\r\n            android:layout_below=\"@id\/button50\"\r\n            android:layout_marginTop=\"20dp\"\r\n            android:onClick=\"showDimension\"\/&gt;\r\n\r\n\r\n    &lt;\/android.support.percent.PercentRelativeLayout&gt;<\/pre>\n<p>Impieghiamo il nuovo <strong>PercentRelativeLayout<\/strong> all&#8217;interno del quale siamo messi in condizione di usare dimensionamenti in percentuale. Lo abbiamo fatto impostando a 50% e 80%\u00a0gli attributi <em>layout_widthPercent<\/em> presenti in entrambi i pulsanti in sostituzione del classico <em>layout_width<\/em>. \u00a0Quest&#8217;ultimo, come ben sappiamo, \u00e8 obbligatorio in qualunque componente, insieme a <em>layout_heigth<\/em>, tanto che,\u00a0nella scrittura del codice, Android Studio ne segnala\u00a0la mancanza permettendo\u00a0tuttavia\u00a0di portare a termine il build dell&#8217;applicazione con successo.<\/p>\n<p>Entrambi i pulsanti, al click, provocheranno l&#8217;invocazione del metodo <em>showDimension<\/em> presente nella MainActivity il quale non far\u00e0 altro che mostrare in una SnackBar la dimensione effettiva del pulsante che, a seconda dei casi, sar\u00e0 proprio il 50% o l&#8217;80% della larghezza del display.<\/p>\n<p>La figura seguente mostra l&#8217;istante immediatamente successivo alla pressione del pulsante con etichetta &#8220;Larghezza 80%&#8221; il quale \u00e8 largo l&#8217;80% di 480.<br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_03.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11509\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_03.jpg\" alt=\"androidpercentsupportlibrary_03\" width=\"376\" height=\"600\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_03.jpg 376w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_03-188x300.jpg 188w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_03-300x479.jpg 300w\" sizes=\"auto, (max-width: 376px) 100vw, 376px\" \/><\/a><\/p>\n<p>Nella visualizzazione landscape il valore che prima era l&#8217;altezza ora rappresenta la larghezza ma il funzionamento \u00e8\u00a0il medesimo. Premendo il pulsante &#8220;Larghezza 50%&#8221; il messaggio nella\u00a0Snackbar ci dimostra\u00a0che \u00e8 largo la met\u00e0 di 800 px.<br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_02.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11511\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_02.jpg\" alt=\"androidpercentsupportlibrary_02\" width=\"600\" height=\"349\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_02.jpg 600w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/11\/androidpercentsupportlibrary_02-300x175.jpg 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><br \/>\nQuello che segue \u00e8 il codice dell&#8217;Activity che risulta nel complesso molto semplice: nell&#8217;<em>onCreate<\/em> vengono inizializzate le TextView e la Toolbar mentre il metodo <em>showDimension<\/em> non fa altro che dirci quanto il pulsante toccato \u00e8 largo.<\/p>\n<pre class=\"lang:java decode:true \">public class MainActivity extends AppCompatActivity {\r\n\r\n    private DisplayMetrics metrics;\r\n\r\n    @Override\r\n    protected void onCreate(Bundle savedInstanceState) {\r\n        super.onCreate(savedInstanceState);\r\n        setContentView(R.layout.activity_main);\r\n        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\r\n        setSupportActionBar(toolbar);\r\n\r\n        metrics = new DisplayMetrics();\r\n        getWindowManager().getDefaultDisplay().getMetrics(metrics);\r\n\r\n        TextView txt= (TextView) findViewById(R.id.txt_larghezzapx);\r\n        txt.setText(Integer.toString(metrics.widthPixels));\r\n\r\n        txt= (TextView) findViewById(R.id.txt_altezzapx);\r\n        txt.setText(Integer.toString(metrics.heightPixels));\r\n\r\n    }\r\n\r\n    public void showDimension(View v)\r\n    {\r\n        Snackbar.make(v, \"Larghezza del pulsante: \"+v.getWidth()+\" px\", \r\n                   Snackbar.LENGTH_LONG).show();\r\n    }\r\n\r\n}<\/pre>\n<h2>Altri aspetti<\/h2>\n<p>Oltre a quello che abbiamo visto si possono\u00a0impostare altri aspetti: l&#8217;altezza con <em>layout_heightPercent<\/em> ma\u00a0anche tutti i margini possibili a seconda che\u00a0parliamo di\u00a0<a href=\"http:\/\/developer.android.com\/reference\/android\/support\/percent\/PercentFrameLayout.html\" target=\"_blank\">PercentFrameLayout<\/a>\u00a0o\u00a0<a href=\"http:\/\/developer.android.com\/reference\/android\/support\/percent\/PercentRelativeLayout.html\" target=\"_blank\">PercentRelativeLayout<\/a>.\u00a0La versione 23.1 della libreria di supporto ha aggiunto anche l&#8217;attributo <em>layout_aspectRatio<\/em> che permette di impostare un rapporto fisso tra le due grandezze (larghezza o altezza)\u00a0cos\u00ec che una di esse sia dichiarata esplicitamente e l&#8217;altra ne sia tratta di conseguenza.<\/p>\n<p>Chiunque abbia programmato in Android sinora non pu\u00f2 non aver notato la mancanza di una soluzione simile nell&#8217;ambito dei layout pertanto sperimentarla \u00e8 d&#8217;obbligo e, come si \u00e8 visto, basta approntare velocemente alcuni pulsanti per valutarne l&#8217;efficacia.<\/p>\n<p>Alla prossima!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>La libreria di supporto del sistema Android \u00e8 stata recentemente arricchita di un nuovo ramo, la Percent&#8230;<\/p>\n","protected":false},"author":561,"featured_media":11568,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[1535,1568,1569,917],"class_list":["post-11495","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorial-pratici","tag-android-developers","tag-android-user-experience","tag-design-user-interface-android","tag-mobile-developers"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11495","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/561"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=11495"}],"version-history":[{"count":18,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11495\/revisions"}],"predecessor-version":[{"id":12109,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11495\/revisions\/12109"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media\/11568"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=11495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=11495"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=11495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}