{"id":12752,"date":"2017-10-05T14:03:39","date_gmt":"2017-10-05T12:03:39","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=12752"},"modified":"2017-10-05T14:03:39","modified_gmt":"2017-10-05T12:03:39","slug":"android-capire-il-funzionamento-dei-fragment","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/android-capire-il-funzionamento-dei-fragment\/","title":{"rendered":"Android: capire il funzionamento dei Fragment"},"content":{"rendered":"<p>Quando si cerca di approfondire i propri studi sulle interfacce Android, il primo scoglio con cui ci si scontra, spesso, sono i <strong>Fragment<\/strong>. Il loro utilizzo non \u00e8 cos\u00ec proibitivo ma ci\u00f2 che li rende ostici \u00e8 la necessit\u00e0 di comprenderne a fondo il ciclo di vita e le basi dell&#8217;interazione\u00a0con l&#8217;ecosistema Android. Con questo articolo ed i successivi, ci interesseremo proprio a questi aspetti.<\/p>\n<h2>Cosa sono i Fragment?<\/h2>\n<p>Un <strong>Fragment<\/strong> pu\u00f2 essere considerato una <strong>porzione dell&#8217;interfaccia utente<\/strong>, completa non solo di layout ma anche di tutto il codice necessario a rappresentarne la logica di gestione. La loro nascita &#8211; risalente ad Android 3.0 &#8211; ha offerto la possibilit\u00e0 di creare interfacce utente composte da porzioni riutilizzabili e alternabili senza la necessit\u00e0 di distruggere l&#8217;Activity. <strong>Un Fragment ha bisogno di un&#8217;Activity che gli faccia da contenitore<\/strong>\u00a0pertanto l&#8217;uso di questi componenti facilita, da un lato, la gestione del ciclo di vita di un&#8217;Activity (visto che questa\u00a0non cambia ma si alternano solo i Fragment) ma dall&#8217;altro aggiunge ulteriore complessit\u00e0 considerando che i Fragment\u00a0\u00a0hanno un proprio ciclo di vita piuttosto articolato.<br \/>\nPer prendere confidenza con la tematica e studiarne gli aspetti pi\u00f9 delicati affronteremo il seguente esempio.<\/p>\n<h2>L&#8217;esempio<\/h2>\n<p>Il progetto (il cui codice \u00e8 <a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/EsempioAndroidFragment.zip\">disponibile qui<\/a>) \u00e8 costituito da una sola Activity con due Fragment che si alternano costituendone l&#8217;interfaccia utente.<br \/>\nNel primo troviamo tre pulsanti, ognuno dei quali etichettato con il nome di una citt\u00e0 italiana.<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-capire-il-funzionamento-dei-fragment_img_01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-12764\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-capire-il-funzionamento-dei-fragment_img_01-191x300.jpg\" alt=\"\" width=\"191\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-capire-il-funzionamento-dei-fragment_img_01-191x300.jpg 191w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-capire-il-funzionamento-dei-fragment_img_01.jpg 382w\" sizes=\"auto, (max-width: 191px) 100vw, 191px\" \/><\/a><\/p>\n<p>Al click di uno di questi, il Fragment viene sostituito con un secondo che mostra una foto ritraente un luogo simbolo della citt\u00e0 in questione accompagnato da un piccolo testo descrittivo (per il quale abbiamo attinto da Wikipedia).<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12776 size-medium\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_01-205x300.jpg\" alt=\"Android gestire l'interfaccia utente dell'Activity con i Fragment\" width=\"205\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_01-205x300.jpg 205w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_01.jpg 410w\" sizes=\"auto, (max-width: 205px) 100vw, 205px\" \/><\/a><\/p>\n<p><strong>Dai nostri Framgment vogliamo un comportamento completo ed efficiente<\/strong> che non trascuri alcun aspetto utile all&#8217;interazione utente.<br \/>\nI nostri obiettivi sono:<\/p>\n<ul>\n<li>quando appare il secondo Fragment (quello con la foto della citt\u00e0, per intenderci) vogliamo che premendo il <strong>tasto Back<\/strong> si torni al primo Fragment (non \u00e8 il comportamento di default) e che appaia la freccia a sinistra per la <strong>navigazione Up<\/strong> sull&#8217;Action Bar: quest&#8217;ultima deve scomparire al ritorno al primo Fragment;<\/li>\n<li>se ruotiamo il dispositivo mentre visualizziamo il secondo Fragment, vogliamo che l&#8217;Activity continui a visualizzarlo a rotazione conclusa in modo che il cambio di configurazione abbia il minimo impatto possibile sulla <em>user experience<\/em>.<\/li>\n<\/ul>\n<h2>Activity e primo Fragment<\/h2>\n<p>Il layout dell&#8217;Activity \u00e8 composto da un FrameLayout:<\/p>\n<pre class=\"lang:xhtml decode:true\">&lt;FrameLayout xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n    android:id=\"@+id\/fragment\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\/&gt;\r\n<\/pre>\n<p>Questo \u00e8 un tipo di layout che serve a mostrare un singolo elemento nell&#8217;interfaccia. <strong>In questo FrameLayout, verranno collocati i nostri Fragment e la loro alternanza sar\u00e0 gestita dal FragmentManager<\/strong>, messo a disposizione dall&#8217;Activity stessa.<\/p>\n<p>I dati utilizzati saranno forniti dalla classe <em>ElencoCitta<\/em> che simula una sorgente dati che nella realt\u00e0 sarebbe rappresentata da un database, un ContentProvider o un&#8217;altra componente che dialoga con la Rete:<\/p>\n<pre class=\"lang:java decode:true \">public class ElencoCitta {\r\n\r\n    private HashMap&lt;String, Citta&gt; citta=new HashMap&lt;String, Citta&gt;();\r\n\r\n    public static class  Citta\r\n    {\r\n        public String nome;\r\n        public String presentazione;\r\n        public int immagine;\r\n\r\n        public Citta(String nome, String presentazione, int immagine) {\r\n            this.nome = nome;\r\n            this.presentazione = presentazione;\r\n            this.immagine=immagine;\r\n        }\r\n    }\r\n\r\n    public ElencoCitta()\r\n    {\r\n        citta.put(\"milano\", new Citta(\r\n                                \"Milano\",\r\n                                \"....\",\r\n                                R.drawable.milano\r\n                        ));\r\n\r\n        citta.put(\"roma\",  new Citta(\r\n                \"Roma\",\r\n                \"....\",\r\n                R.drawable.roma\r\n        ));\r\n\r\n        citta.put(\"palermo\", new Citta(\r\n                \"Palermo\",\r\n                 \"....\",\r\n                R.drawable.palermo\r\n        ));\r\n    }\r\n\r\n    public Citta trovaCitta(String nomeCitta)\r\n    {\r\n        return citta.get(nomeCitta);\r\n    }\r\n\r\n\r\n\r\n}<\/pre>\n<p>Nell&#8217;Activity, <strong>gestiremo il passaggio tra un Fragment e l&#8217;altro mediante una FragmentTransaction<\/strong>. Questa \u00e8 costituita dalle seguenti fasi:<\/p>\n<ul>\n<li>viene <strong>creata una nuova FragmentTransaction<\/strong> dal FragmentManager;<\/li>\n<li>viene eseguita l&#8217;operazione che si vuole svolgere che consiste tipicamente nell&#8217;aggiunta di un Fragment ad un FrameLayout (metodo <em>add<\/em>), nella sua sostituzione (metodo <em>replace<\/em>) o nella sua rimozione (metodo <em>remove<\/em>);<\/li>\n<li>chiediamo\u00a0di rendere operativa la modifica con l&#8217;invocazione del metodo <em>commit<\/em>.<\/li>\n<\/ul>\n<p>Ci\u00f2 lo faremo nel metodo <em>cambiaFragment<\/em> che risponde al <em>click<\/em> su uno dei tre pulsanti presenti nel primo Fragment. Questo \u00e8 il codice completo dell&#8217;Activity.<\/p>\n<pre class=\"lang:java decode:true\">public class MainActivity extends AppCompatActivity {\r\n\r\n    private ElencoCitta elenco;\r\n\r\n    @Override\r\n    public void onBackPressed() {\r\n        getSupportActionBar().setDisplayHomeAsUpEnabled(false);\r\n        super.onBackPressed();\r\n    }\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\r\n        elenco=new ElencoCitta();\r\n\r\n        FragmentManager fm = getSupportFragmentManager();\r\n        Fragment trovato=fm.findFragmentByTag(CittaFragment.CITTAFRAGMENT_TAG);\r\n\r\n        FragmentTransaction ft = fm.beginTransaction();\r\n        if (trovato!=null) {\r\n            ft.replace(R.id.fragment, trovato);\r\n            getSupportActionBar().setDisplayHomeAsUpEnabled(true);\r\n        }\r\n        else\r\n            ft.replace(R.id.fragment, new MainFragment());\r\n        ft.commit();\r\n    }\r\n\r\n\r\n    public void cambiaFragment(View v)\r\n    {\r\n        CittaFragment fragment=null;\r\n        switch(v.getId())\r\n        {\r\n            case R.id.roma:\r\n                fragment=CittaFragment.newInstance(elenco.trovaCitta(\"roma\"));\r\n                break;\r\n            case R.id.milano:\r\n                fragment=CittaFragment.newInstance(elenco.trovaCitta(\"milano\"));\r\n                break;\r\n            case R.id.palermo:\r\n                fragment=CittaFragment.newInstance(elenco.trovaCitta(\"palermo\"));\r\n        }\r\n        FragmentManager fm = getSupportFragmentManager();\r\n        FragmentTransaction ft = fm.beginTransaction();\r\n        ft.addToBackStack(null);\r\n        ft.replace(R.id.fragment, fragment,CittaFragment.CITTAFRAGMENT_TAG);\r\n        ft.commit();\r\n\r\n        getSupportActionBar().setDisplayHomeAsUpEnabled(true);\r\n    }\r\n\r\n    @Override\r\n    public boolean onOptionsItemSelected(MenuItem item) {\r\n        switch (item.getItemId()) {\r\n            case android.R.id.home:\r\n                getSupportFragmentManager().popBackStack();\r\n                getSupportActionBar().setDisplayHomeAsUpEnabled(false);\r\n                break;\r\n        }\r\n        return false;\r\n    }\r\n\r\n}<\/pre>\n<p>Il<strong> primo Fragment<\/strong>, classe <em>MainFragment<\/em>, ha un codice molto semplice:<\/p>\n<pre class=\"lang:java decode:true\">public class MainFragment extends Fragment {\r\n\r\n\r\n    @Override\r\n    public View onCreateView(LayoutInflater inflater, ViewGroup container, \r\n Bundle savedInstanceState) {\r\n        return inflater.inflate(R.layout.fragment_main, container, false);\r\n    }\r\n\r\n}<\/pre>\n<p>La classe \u00e8 un&#8217;estensione di Fragment e al suo interno implementa il metodo <strong>onCreateView<\/strong>, facente parte del ciclo di vita di un Fragment. Come approccio iniziale, preferiamo non mostrare subito tutte le fasi del ciclo di vita ma affrontare i metodi man mano che ne abbiamo bisogno lasciando ad articoli successivi una visione pi\u00f9 d&#8217;insieme.<\/p>\n<p>Nel metodo <em>onCreateView<\/em> deve essere caricato il layout del Fragment con l&#8217;inizializzazione dell&#8217;interfaccia. In questo caso, carichiamo tramite <em>LayoutInflater<\/em> il layout che include i tre pulsanti.<\/p>\n<pre class=\"lang:xhtml decode:true\">&lt;RelativeLayout xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"&gt;\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=\"300dp\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:orientation=\"vertical\"\r\n        android:layout_centerInParent=\"true\"&gt;\r\n\r\n        &lt;Button\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:text=\"Roma\"\r\n            android:onClick=\"cambiaFragment\"\r\n            android:id=\"@+id\/roma\"\/&gt;\r\n\r\n        &lt;Button\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:text=\"Milano\"\r\n            android:id=\"@+id\/milano\"\r\n            android:onClick=\"cambiaFragment\"\r\n            android:layout_marginTop=\"20dp\"\/&gt;\r\n\r\n        &lt;Button\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:text=\"Palermo\"\r\n            android:id=\"@+id\/palermo\"\r\n            android:onClick=\"cambiaFragment\"\r\n            android:layout_marginTop=\"20dp\"\/&gt;\r\n    &lt;\/LinearLayout&gt;\r\n\r\n&lt;\/RelativeLayout&gt;<\/pre>\n<p>Per quanto riguarda la gestione del loro evento di pressione avremmo potuto gestirlo internamente al Fragment con gli appositi Listener ma visto che le operazioni richiamate riguardano l&#8217;Activity nel suo complesso abbiamo preferito utilizzare l&#8217;attributo <em>onClick<\/em> che punta al metodo <em>cambiaFragment<\/em> dell&#8217;Activity. A seconda dei casi, ci si potr\u00e0 regolare personalmente se si vuole gestire gli eventi all&#8217;interno del Fragment o meno ma questo dipender\u00e0 spesso dal tipo di operazioni che si devono affrontare.<\/p>\n<h2>L&#8217;Activity, aspetti rilevanti<\/h2>\n<p>Dopo aver introdotto il codice dell&#8217;Activity, notiamo alcuni aspetti particolari. Al momento di eseguire la <em>FragmentTransaction<\/em> nel metodo <em>cambiaFragment<\/em>, invochiamo il metodo <em>addToBackStack<\/em>. Questo serve a fare in modo che\u00a0il Fragment sostituito venga aggiunto in una sorta di storico chiamato BackStack cosicch\u00e8, al momento della pressione del pulsante <em>Back<\/em> mentre il secondo Fragment \u00e8 visualizzato, l&#8217;Activity non venga chiusa ma si inverta l&#8217;ultima transazione eseguita riportando alla luce il primo Fragment. Senza l&#8217;uso di <em>addToBackStack<\/em>, al momento della pressione del tasto <em>Back<\/em>, l&#8217;Activity verrebbe chiusa.<\/p>\n<p>Notiamo ancora l&#8217;invocazione del metodo <em>replace<\/em>:<\/p>\n<pre class=\"lang:java decode:true\">ft.replace(R.id.fragment, fragment,CittaFragment.CITTAFRAGMENT_TAG);<\/pre>\n<p>I tre parametri passati sono l&#8217;id del FrameLayout che ospiter\u00e0 il Fragment, l&#8217;oggetto Fragment che subentrer\u00e0 ed infine &#8211; cosa che ci interessa in questo discorso &#8211; una costante stringa che svolger\u00e0 il ruolo di <strong>tag del Fragment<\/strong>. Il tag permetter\u00e0 in seguito di identificare il Fragment chiedendo al <em>FragmentManager<\/em> il suo ripristino e ci\u00f2 torner\u00e0 utile nel metodo <em>onCreate\u00a0<\/em>al momento della ricostruzione dell&#8217;Activity dopo la rotazione del dispositivo:<\/p>\n<pre class=\"lang:java decode:true\"> FragmentManager fm = getSupportFragmentManager();\r\n        Fragment trovato=fm.findFragmentByTag(CittaFragment.CITTAFRAGMENT_TAG);\r\n\r\n        FragmentTransaction ft = fm.beginTransaction();\r\n        if (trovato!=null) {\r\n            ft.replace(R.id.fragment, trovato);\r\n            getSupportActionBar().setDisplayHomeAsUpEnabled(true);\r\n        }\r\n        else\r\n            ft.replace(R.id.fragment, new MainFragment());\r\n        ft.commit();<\/pre>\n<p>Senza il precedente codice, ruotando il dispositivo durante la visualizzazione del secondo Fragment, alla ricostruzione dell&#8217;Activity verrebbe mostrato il primo Fragment costringendo l&#8217;utente a dover ripristinare il contenuto che stava leggendo un attimo prima.<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_02.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-12775\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_02-300x174.jpg\" alt=\"Android gestire l'interfaccia utente dell'Activity con i Fragment\" width=\"300\" height=\"174\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_02-300x174.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_02-768x445.jpg 768w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_02-1024x593.jpg 1024w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2017\/01\/android-nuova_img_02.jpg 1038w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Altro aspetto che gestiamo \u00e8 l&#8217;apparizione dell&#8217;icona a forma di freccia verso sinistra sull&#8217;ActionBar che si utilizza per la navigazione Up. Essa apparir\u00e0 solo mentre il secondo Fragment \u00e8 sullo schermo e gestiremo la sua apparizione con l&#8217;invocazione:<\/p>\n<pre class=\"lang:java decode:true\">getSupportActionBar().setDisplayHomeAsUpEnabled(true);<\/pre>\n<p>mentre l&#8217;evento di click su di essa andr\u00e0 gestito come una normale <em>action<\/em>:<\/p>\n<pre class=\"lang:java decode:true \"> public boolean onOptionsItemSelected(MenuItem item) {\r\n        switch (item.getItemId()) {\r\n            case android.R.id.home:\r\n                getSupportFragmentManager().popBackStack();\r\n                getSupportActionBar().setDisplayHomeAsUpEnabled(false);\r\n                break;\r\n        }\r\n        return false;\r\n    }<\/pre>\n<p>Il metodo <em>popBackStack<\/em> esegue l&#8217;inverso di <em>addToBackStack<\/em> visto prima: estrae dal BackStack l&#8217;ultimo Fragment archiviato.<\/p>\n<p>Inoltre aggiungiamo l&#8217;overrride del metodo <em>onBackPressed<\/em> che permette di personalizzare la pressione del pulsante Back: quello che vi inseriremo noi sar\u00e0 la disabilitazione della frecciolina di navigazione Up:<\/p>\n<pre class=\"lang:java decode:true\">public void onBackPressed() {\r\n        getSupportActionBar().setDisplayHomeAsUpEnabled(false);\r\n        super.onBackPressed();\r\n    }<\/pre>\n<h2>Il secondo Fragment<\/h2>\n<p>Il secondo Fragment mostra ancora il metodo <em>onCreateView<\/em> in cui viene preparata l&#8217;interfaccia ma troviamo anche un altro metodo del ciclo di vita, <em>onCreate<\/em>, che -analogamente a quello utilizzabile nelle Activity &#8211; gestisce la creazione del Fragment e viene invocato prima di <em>onCreateView<\/em>.<\/p>\n<p>L&#8217;aspetto interessante di questo Fragment consiste nell&#8217;utilizzo del metodo <em>newInstance<\/em>. Vediamo il codice completo:<\/p>\n<pre class=\"lang:java decode:true \">public class CittaFragment extends Fragment {\r\n\r\n    public static final String CITTAFRAGMENT_TAG=\"CITTAFRAGMENT_TAG\";\r\n\r\n    private static final String ARG_ID_IMG = \"img\";\r\n    private static final String ARG_NOME_CITTA = \"nome\";\r\n    private static final String ARG_DESCR_CITTA = \"descr\";\r\n\r\n    private String nomeCitta;\r\n    private String descrizioneCitta;\r\n    private int idImg;\r\n\r\n\r\n    public static CittaFragment newInstance(ElencoCitta.Citta citta) {\r\n        CittaFragment fragment = new CittaFragment();\r\n        Bundle args = new Bundle();\r\n        args.putInt(ARG_ID_IMG, citta.immagine);\r\n        args.putString(ARG_NOME_CITTA, citta.nome);\r\n        args.putString(ARG_DESCR_CITTA, citta.presentazione);\r\n        fragment.setArguments(args);\r\n        return fragment;\r\n    }\r\n\r\n    @Override\r\n    public void onCreate(Bundle savedInstanceState) {\r\n        super.onCreate(savedInstanceState);\r\n        if (getArguments() != null) {\r\n            idImg = getArguments().getInt(ARG_ID_IMG);\r\n            nomeCitta = getArguments().getString(ARG_NOME_CITTA);\r\n            descrizioneCitta = getArguments().getString(ARG_DESCR_CITTA);\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r\n                             Bundle savedInstanceState) {\r\n        View v=inflater.inflate(R.layout.fragment_citta, container, false);\r\n\r\n        ImageView imageView= (ImageView) v.findViewById(R.id.imageView);\r\n        TextView txt_nome= (TextView) v.findViewById(R.id.citta);\r\n        TextView txt_descr= (TextView) v.findViewById(R.id.descrizione);\r\n\r\n        imageView.setImageResource(idImg);\r\n        txt_nome.setText(nomeCitta);\r\n        txt_descr.setText(descrizioneCitta);\r\n        return v;\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>Quando creiamo il Fragment vogliamo passargli dall&#8217;Activity i dati da mostrare che consistono nell&#8217;id dell&#8217;immagine da visualizzare, il nome della citt\u00e0 e la breve descrizione. Normalmente, lo faremmo con un costruttore con parametri ma questa pratica \u00e8 sconsigliata e scoraggiata. Piuttosto si preferisce creare<strong> un metodo statico<\/strong> &#8211; per convenzione chiamato <em>newInstance<\/em> &#8211; che riceva i parametri necessari e <strong>restituisca un Fragment secondo il pattern Factory<\/strong>. Prima di restituire il Fragment il metodo <em>newInstance<\/em> avr\u00e0 cura di inserirvi i dati necessari con <em>setArguments<\/em>. Questi potranno essere recuperati con <em>getArguments<\/em> nel metodo <em>onCreate<\/em>.<\/p>\n<p>I parametri passati vengono inseriti in un <em>Bundle<\/em>. Nel nostro caso dovevamo passare un oggetto Citta che per\u00f2 non pu\u00f2 diventare parte di un Bundle a meno che non venga reso <em>Serializable<\/em> o <em>Parcelable<\/em>. Quest&#8217;ultima opzione soprattutto sarebbe una buona prassi ma per non complicare troppo l&#8217;esempio abbiamo preferito estrarre dall&#8217;oggetto il numero intero e le due stringhe ed inserirle nel Bundle. In alternativa, avremmo potuto rinunciare all&#8217;uso degli <em>arguments<\/em> di un Fragment creando un metodo &#8211; tipo <em>setter &#8211;<\/em>\u00a0cui passare direttamente l&#8217;oggetto di classe Citta.<\/p>\n<h2>Conclusioni<\/h2>\n<p>Bench\u00e8 l&#8217;esempio mostrato sia piuttosto semplice ha il pregio di illustrare l&#8217;uso dei Fragment in una modalit\u00e0 che non si accontenta di presentare solo gli aspetti pi\u00f9 essenziali ma di indagare le vere questioni legate alla navigazione attraverso l&#8217;applicazione che vanno affrontate necessariamente in casi reali. I Fragment non appaiono spesso una tematica molto intuitiva e proprio per questo abbiamo deciso di dedicarvi alcuni articoli di approfondimento: questo che vi abbiamo offerto \u00e8 il primo ma non ne mancheranno altri.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quando si cerca di approfondire i propri studi sulle interfacce Android, il primo scoglio con cui ci&#8230;<\/p>\n","protected":false},"author":561,"featured_media":13222,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1682,1],"tags":[1278,1737,1215,1569,1869],"class_list":["post-12752","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","category-tutorial-pratici","tag-android","tag-creare-app-mobile","tag-design-user-interface","tag-design-user-interface-android","tag-fragment"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/12752","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=12752"}],"version-history":[{"count":7,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/12752\/revisions"}],"predecessor-version":[{"id":12779,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/12752\/revisions\/12779"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media\/13222"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=12752"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=12752"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=12752"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}