Autore Topic: Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar  (Letto 11191 volte)

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
+3
Livello di difficoltà: facile
Target SDK: 17
Min SDK: 8
Link al file compresso del progetto eclipse: file in allegato

Il tutorial descrive come utilizzare i Menu in presenza di una ActionBar o di una SherlockActionBar.
Esiste un tutorial che descrive ampiamente cosa sono i menù e lo potete trovare in questo link Uso dei Menu.
Questo tutorial ne estende il contenuto, descrivendone il comportamento in presenza della ActionBar e di Fragment.

Il comportamento del Options Menu cambia in Android con l'introduzione della ActionBar (introdotta con Android 3.0 - API 11).
Fino alla versione 2.3.x (API 10) il menu appariva in fondo alla videata alla pressione del tasto (hardware) Menu.
Con Android 3.0 il bottone menù è stato reso opzionale, e il menù è stato sostituito dalla ActionBar e dall'overflow menù.

Come inserire un Options Menù nella ActionBar in una Activity
L'inserimento di un menù può essere eseguito, come in precedenza, in maniera programmatica o tramite l'utilizzo di un file xml.
In entrambi i casi la creazione del Menù avviene all'interno del metodo onCreateOptionsMenu(Menu menu).
Codice (Java): [Seleziona]
public class ActionBarActivity extends Activity {
   
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.action_bar, menu);
                return true;
        }
}
In questo caso eseguiamo l'inserimento tramite un file xml che si chiama action_bar.xml e posizionato nella cartella /res/menu.
Codice (XML): [Seleziona]
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
       android:id="@+id/menu_add"
       android:orderInCategory="100"
       android:showAsAction="always"
       android:icon="@drawable/action_add"
       android:title="@string/menu_add"/>
   
    <item
       android:id="@+id/menu_refresh"
       android:orderInCategory="100"
       android:showAsAction="ifRoom|withText"
       android:icon="@drawable/action_add"
       android:title="@string/menu_refresh"/>
   
   
    <item
       android:id="@+id/action_settings"
       android:orderInCategory="100"
       android:showAsAction="never"
       android:title="@string/action_settings"/>

</menu>
Questo codice può essere eseguito su qualsiasi dispositivo Android.
Su un sistema 2.3.x o inferiore (API 10-) avremmo lo stesso comportamento descritto nel precedente tutorial.
Su un sistema 3.0 o superiori (API 11+) gli item del Menu verranno inseriti nella ActionBar.

Qui sotto trovate le due immagini dei due differenti casi.

Comportamento con ActionBar. (Android 3.0+)



Comportamento senza  ActionBar - Android 2.3.x  (volutamente non ho inserito la icon su setting...ma andrebbero usate icone differenti per via del diverso style, ma esula dallo scopo del tutorial)



Esistono alcune differenze.
Innanzitutto il metodo onCreateOptionsMenu viene eseguito in due momenti differenti.
Nei dispositivi 2.3.x il metodo viene eseguito quando l'utente clicca per la prima volta il pulsante hardware Menu.
Nel caso di dispositivi 3.0+ il metodo viene eseguito nel momento della creazione della Activity.

Il miglior modo di verificare questo comportamento è utilizzare il debug.
In un dispositivo Android 3.0+ abbiamo questo comportamento:



In un dispositivo Android 2.3.x abbiamo questo comportamento:



Un'altra grande differenza è l'overflow Menu.
Con Android 3.0 i singoli item menu vengono visualizzati nella action bar.
Lo spazio disponibile dipende dal dispositivo e dall'orientamento, e potrebbe non essere sufficiente a contenere tutte le voci.
Tutti gli item che non trovano spazio vengono posizionati nell'overflow menu (che ha sostituito il More o Altro nel vecchio menù).
L'overflow menu in genere si presenta con i 3 puntini verticali ed è posizionato in modo visibile (di default) a destra nella ActionBar.
Nei dispositivi 3.0+ con ancora un pulsante hardware Menu, appare invece al click dello stesso pulsante.

Il comportamento di default può essere modificato attraverso l'attributo android:showAsAction.
E' molto importante seguire le linee guida, proposte da Android, affinchè si costruiscano interfacce familiari per un utente.
Android permette di customizzare tutto, ma un utente acquisisce familiarità con i comportamenti del suo device; se la nostra applicazione ha un comportamento che si discosta dallo standard, ha una probabilità superiore che venga presto dismessa e abbondanata.

In questa pagina trovate la logica o algoritmo con il quale android determina quanti item possono essere visibili su un determinato dispositivo. In questa altra pagina invece trovate le indicazioni sulla base delle quali scegliere quali item mettere in una determinata videata, in funzione del suo utilizzo.
E' intuitivo pensare che è logico inserire le funzioni utilizzati più frequentemente in un determinato schermo.

Questo attributo può assumere i seguenti valori:
android:showAsAction=["ifRoom" | "never" | "withText" | "always" | "collapseActionView"]

Specificando il valore "never" le voci saranno inserite direttamente nell'overflow menù; utilizzando "ifRoom" l'item viene inserito in ActionBar solo se lo spazio è sufficiente.
Normalmente è preferibile utilizzare "ifRoom" poichè il valore "always" va gestito con particolare cura e ne è consigliato l'utilizzo in pochissimi casi, perchè va a forzare un comportamento.

Il valore "withText" consente, spazio permettendo di visualizzare oltre l'icona anche il testo.
Questo valore può essere utilizzando abbinandolo ad un altro valore, per esempio è possibile specificare android:showAsAction="ifRoom|withText".

Qui sotto trovate il comportamento della stessa Activity vista sopra in un tablet, dove lo spazio consente l'inserimento del testo e dell'icona.


Vanno anche tenute presenti alcune regole:
  • L'overflow menu mostra solo il testo, mentre i device con android 2.3.x mostrano anche l'icona.Per questo motivo è importante valorizzare sia android:icon sia android:title
  • android:title andrebbe sempre valorizzato. Infatti un Item può finire nell'overflow menù e in quel caso verrebbe mostrato solo quel valore
  • Sde l'utente tiene premuto a lungo l'icona, appare come tooltip il valore di android:title
  • checkboxes, radio buttons, shortcut keys e menù non sono visualizzati negli Item Menu presenti in Action Bar, mentre lo sono nell'overflow menù

L'ordine di visualizzazione di default è definito con l'ordine con cui sono definiti nel file xml.
E' possibile intervenire anche in questo caso attraverso l'attributo android:orderInCategory.
Questo attributo riveste una particolare importanza, in relazione allo spazio disponibile nel momento in cui non tutti gli item possono essere visualizzati nella ActionBar.

Per un elenco esaustivo degli attributi presenti nel file xml, la pagina di riferimento è questa.
Tra le novità legata ad Android 3.0+ c'è l'inserimento dell'attributo android:onClick="method name" che permette di specificare direttamente nel file xml il nome del metodo che verrà chiamato nella Action.

Quanto un item viene cliccato viene lanciato il metodo onOptionsItemSelected()(come del resto nelle versioni precedenti).
Come spiegato nell'altro tutorial il metodo item.getItemId() permette di identificare l'id del menu che è stato premuto.
Codice (Java): [Seleziona]
    @Override
        public boolean onOptionsItemSelected(MenuItem item) {
                switch (item.getItemId()) {
                case android.R.id.home:
                        NavUtils.navigateUpFromSameTask(this);
                        return true;
                case R.id.menu_add:
                        Toast.makeText(this, "Add item", 2500).show();
                        return true;
                case R.id.menu_refresh:
                        Toast.makeText(this, "Refresh item", 2500).show();
                        return true;
                case R.id.menu_settings:
                        Toast.makeText(this, "Setting item", 2500).show();
                        return true;
                }
                return super.onOptionsItemSelected(item);
        }

E' possibile intervenire dinamicamente nella creazione del menù attraverso il metodo onPreparedOptionsMenu(Menu menu).
Cambia in funzione del livello di API il momento in cui viene chiamato.
Questo metodo viene lanciato quando si preme il tasto hardware Menù, quando l'ActionBar è creata e quando viene visualizzato l'overflow Menu.

Codice (Java): [Seleziona]
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
         MenuItem menuItem = menu.findItem(MENU_ITEM);
         
                 [ ... modify Menu Items ... ]
         return true;
    }

Come ho detto in precedenza, il menù può essere costruito attraverso un file xml, oppure attraverso codice java.
In questo caso valgono le stesse considerazioni viste nell'altro tutorial, tenendo presente che l'utilizzo del file xml è considerato al momento una best pratice.


Come inserire un Options Menu nella SherlockActionBar
Come specificato sopra l'ActionBar è stata introdotta con le API 11 e al momento in cui scrivo non è stata inserita nella support library.
Se vogliamo uniformare il comportamento la migliore soluzione al momento è l'utilizzo della SherlockActionBar. (eventuali indicazioni su come inserirla in un vostro progetto potete fare riferimento a questo tutorial).

Per utilizzare gli Options Menu, e avere un comportamento uniforme, nel nostro codice dovremmo apportare solo piccole modifiche.
E' bene ricordare che Menu, MenuItem e MenuInflater non sono quelli presenti nel package standard android.view. ma quelli presenti nel package com.actionbarsherlock.view.

E' sufficiente modificare la riga di codice   
Codice (Java): [Seleziona]
     getMenuInflater().inflate(R.menu.action_bar, menu);in   
Codice (Java): [Seleziona]
     getSupportMenuInflater().inflate(R.menu.action_bar, menu);
Il nostro codice finale diventa:
Codice (Java): [Seleziona]
public class SherlockActionBarActivity extends SherlockActivity {
@Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getSupportMenuInflater().inflate(R.menu.action_bar, menu);
                return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
                switch (item.getItemId()) {
                case android.R.id.home:
                        NavUtils.navigateUpFromSameTask(this);
                        return true;
                case R.id.menu_add:
                        Toast.makeText(this, "Add item", 2500).show();
                        return true;
                case R.id.menu_refresh:
                        Toast.makeText(this, "Refresh item", 2500).show();
                        return true;
                case R.id.menu_settings:
                        Toast.makeText(this, "Setting item", 2500).show();
                        return true;
                }
                return super.onOptionsItemSelected(item);
        }
}
Il vantaggio di questa seconda Activity è quello di avere un unico corportamento unificato fra le diversi versioni di Android.
Qui sotto trovate le due immagini, e noterete che l'unico comportamento che differisce è l'overflow menu.
Come indicato nel paragrafo precedente, l'overflow menù è presente nella actionBar se non è presente un bottone hardware. Nei dispositivi dove è presente, l'overflow menù appare comunque al click del pulsante fisico.

Comportamento con Android 3.0+



Comportamento con Android 2.3.x




Come inserire un Options Menu in un Fragment
Vedremo in questo esempio come gestire il Menù in presenza di una Activity che contiene un fragment.

Abbiamo una nostra Activity che ha un proprio menu.
Codice (Java): [Seleziona]
public class MyFragmentActivity extends FragmentActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_fragment);
               
                getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment, ActionBarFragment.newInstance()).commit();
        }

        @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.action_fragmentactivity_bar, menu);
        return true;
    }

Il menù è definito in un file xml
Codice (XML): [Seleziona]
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
       android:id="@+id/menu_refresh"
       android:icon="@drawable/action_refresh"
       android:orderInCategory="100"
       android:showAsAction="ifRoom|withText"
       android:title="@string/menu_refresh"/>
   
    <item
       android:id="@+id/menu_settings"
       android:orderInCategory="100"
       android:showAsAction="never"
       android:title="@string/menu_settings"/>

</menu>

Il fatto che stia utilizzando la support library (e quindi FragmentActivity piuttosto che Activity) è solo per garantire la compatibilità dei vecchi device.
Le considerazioni rimangono le stesse.

Abbiamo quindi un Fragment che viene inserito all'interno della Activity.
Innanzitutto è indispensabile specificare all'interno del metodo onCreate() del fragment la chiamata a setHasOptionsMenu(true);
Codice (Java): [Seleziona]
public class ActionBarFragment extends Fragment {

        public static ActionBarFragment newInstance() {
                ActionBarFragment fragment = new ActionBarFragment();
                return fragment;
        }
       
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setHasOptionsMenu(true);
        }
       
        @Override
        public void onCreateOptionsMenu( Menu menu, MenuInflater inflater) {   
           inflater.inflate(R.menu.action_fragment, menu);
        }

Il menu anche in questo caso è definito in un file xml.
Codice (XML): [Seleziona]
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
       android:id="@+id/menu_add"
       android:orderInCategory="100"
       android:showAsAction="always"
       android:icon="@drawable/action_add"
       android:title="@string/menu_add"/>
       
</menu>

E' importante conoscere l'ordine con il quale, vengono popolati i menù.
Il miglior modo di verificarlo è utilizzare il debug.
Viene prima chiamato il metodo onCreateOptionsMenu(Menu menu) presente nella Activity e quindi il metodo onCreateOptionsMenu( Menu menu, MenuInflater inflater) presente nel Fragment.

Qui sotto trovate l'immagine di quello che otteniamo.


E' importante l'ordine con il quale vengono inserite.
Vedete che negli item visibili è presente prima il tasto Refresh che è definito nell'activity e quindi il tasto Add definito nel fragment.

Come specificato sopra, è possibile intervenire anche in questo caso attraverso l'attributo android:orderInCategory.
Se modifichiamo il file xml utilizzato nel fragment in questo modo
Codice (XML): [Seleziona]
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
       android:id="@+id/menu_add"
       android:orderInCategory="50"
       android:showAsAction="always"
       android:icon="@drawable/action_add"
       android:title="@string/menu_add"/>
       
</menu>

otteniamo questo risultato:


Quando si utilizza l'attributo android:orderInCategory è importante ricordare che se non specificato il default è 0.
Questo implica che a meno che vogliamo dargli la priorità più alta, dobbiamo necessariamente impostare quel valore per tutti gli item , impostando adeguatamente i valori.

Quando un item viene cliccato viene lanciato il metodo onOptionsItemSelected(MenuItem item)
Anche qui bisogna prestare attenzione all'ordine con i quali vengono eseguiti.
Viene prima eseguito il metodo presente nella Activity, quindi viene eseguito il metodo nel Fragment ma solo se il precedente metodo non ha consumato l'evento.
Questo dettaglio è essenziale.
Nella nostra activity è importante eseguire return super.onOptionsItemSelected(item) se non ho intercettato alcun evento.
Codice (Java): [Seleziona]
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
                switch (item.getItemId()) {
                case android.R.id.home:
                        NavUtils.navigateUpFromSameTask(this);
                        return true;
                case R.id.menu_refresh:
                        Toast.makeText(this, "Refresh item", 2500).show();
                        return true;
                case R.id.menu_settings:
                        Toast.makeText(this, "Setting item", 2500).show();
                        return true;
                }
                return super.onOptionsItemSelected(item);
        }

Come inserire un Options Menu in un Fragment e SherlockActionBar
Per completezza riporto anche il caso in cui si voglia utilizzare la SherlockActionBar con i Fragment.
Le considerazioni sono le stesse viste sopra (Options menu con Fragment), il codice va solamente adeguato.

Questa è la nostra Activity in cui abbiamo adeguato gli import e alcune parti di codice.
Codice (Java): [Seleziona]
public class MySherlockFragmentActivity extends SherlockFragmentActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_fragment);
               
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
               
                getSupportFragmentManager().beginTransaction().
                        replace(R.id.fragment,ActionBarSherlockFragment.newInstance()).commit();
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
               // Inflate the menu; this adds items to the action bar if it is present.
               getSupportMenuInflater().inflate(R.menu.action_fragmentactivity_bar, menu);
              return true;
    }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
                switch (item.getItemId()) {
                case android.R.id.home:
                        NavUtils.navigateUpFromSameTask(this);
                        return true;
                case R.id.menu_refresh:
                        Toast.makeText(this, "Refresh item", 2500).show();
                        return true;
                case R.id.menu_settings:
                        Toast.makeText(this, "Setting item", 2500).show();
                        return true;
                }
                return super.onOptionsItemSelected(item);
        }
}
Questo è il nostro Fragment adeguato:
Codice (Java): [Seleziona]
public class ActionBarSherlockFragment extends SherlockFragment {

        /**
         * Use this factory method to create a new instance of this fragment using
         * the provided parameters.
         *
         */

        public static ActionBarSherlockFragment newInstance() {
                ActionBarSherlockFragment fragment = new ActionBarSherlockFragment();
                return fragment;
        }

        public ActionBarSherlockFragment() {
                // Required empty public constructor
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setHasOptionsMenu(true);
        }

        @Override
        public void onCreateOptionsMenu( Menu menu, MenuInflater inflater) {   
                inflater.inflate(R.menu.action_fragment, menu);
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
                switch (item.getItemId()) {
                case R.id.menu_add:
                        Toast.makeText(getActivity(), "Add item", 2500).show();
                        return true;

                }
                return super.onOptionsItemSelected(item);
        }
       
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                        Bundle savedInstanceState) {
                // Inflate the layout for this fragment
                return inflater.inflate(R.layout.fragment_action_bar, container, false);
        }

}

Qui sotto trovate l'immagine su un dispositvo Android 2.3.x


Nell'allegato trovate tutte le immagini utilizzate.
I sorgenti del progetto TestAbsProject li trovate aggiornati su GitHub TestAbsProject

Bibliografia:

Offline MisterHide

  • Utente junior
  • **
  • Post: 65
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Windows XP
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #1 il: 20 Marzo 2013, 11:32:10 CET »
0
Grazie per l'esaustivo Tutorial, l'ho trovato molto semplice ma allo stesso tempo completo.

Una cosa però volevo chiederti.
Io utilizzo la Sherlock e vorrei poter modificare l'aspetto della ActionBar o delle Tab : tipo l'altezza, lo sfondo e quant'altro ?

grazie ancora.

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #2 il: 20 Marzo 2013, 13:47:11 CET »
0
@GabMarioPower: fai delle guide davvero suprlative e ben strutturate. Grazie mille per l'impegno :-)

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #3 il: 20 Marzo 2013, 17:08:53 CET »
0
Grazie per l'esaustivo Tutorial, l'ho trovato molto semplice ma allo stesso tempo completo.

Una cosa però volevo chiederti.
Io utilizzo la Sherlock e vorrei poter modificare l'aspetto della ActionBar o delle Tab : tipo l'altezza, lo sfondo e quant'altro ?

grazie ancora.

Se vuoi personalizzare la ActionBar ti consiglio di utilizzare il tool di Jeff Gilfelt che puoi trovare qui http://jgilfelt.github.com/android-actionbarstylegenerator/.
Per quanto riguarda l'altezza, personalmente non la modificherei, preferisco utilizzare i pattern standard di Android.
Cambiare l'altezza potrebbe implicare altre modifiche, come quelle delle icone che andrebbero adeguate.


Offline MisterHide

  • Utente junior
  • **
  • Post: 65
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Windows XP
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #4 il: 20 Marzo 2013, 17:41:54 CET »
0
Intanto grazie mille per la risposta.  :-)

Io volevo solo modificare l'altezza delle tab e lì non si cono icone.
Questo perchè tra action-bar e tab ho occupato 1/4 dello schermo  :-(

Intanto controllo il link che mi hai postato, se nel frattempo (naturalmente quando hai un minuto da dedicarmi) mi puoi dire come risolvere il probl. dell'altezza te ne sarei grato.

Ancora grazie.



Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #5 il: 20 Marzo 2013, 18:16:41 CET »
0
Intanto grazie mille per la risposta.  :-)

Io volevo solo modificare l'altezza delle tab e lì non si cono icone.
Questo perchè tra action-bar e tab ho occupato 1/4 dello schermo  :-(

Intanto controllo il link che mi hai postato, se nel frattempo (naturalmente quando hai un minuto da dedicarmi) mi puoi dire come risolvere il probl. dell'altezza te ne sarei grato.

Ancora grazie.

Non ne sono sicurissimo, ma l'altezza della ActionBar e dei tab è determinata da un unico attributo actionBarSize. Quindi non puoi cambiare solo i Tab.
Anche qui, ti consiglio di seguire i pattern..... e di lasciare il comportamento standard.
Codice (XML): [Seleziona]
<style name="YourTheme" parent="......">
    <item name="android:actionBarSize">XXdp</item>
    ..
</style>

Eventualmente ti consiglio di aprire un topic separato.

Offline MisterHide

  • Utente junior
  • **
  • Post: 65
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Windows XP
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #6 il: 20 Marzo 2013, 18:26:31 CET »
0
Ok grazie, sto facendo delle prove, eventualmente seguo il tuo consiglio e apro un topic nuovo.

Buona serata.

Offline Trigun

  • Utente normale
  • ***
  • Post: 183
  • Respect: +4
    • Mostra profilo
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #7 il: 08 Aprile 2013, 10:20:50 CEST »
0
domanda forse banale...
se voglio mettere un icona anche alle opzioni che stanno raggruppate?

Offline dom4

  • Utente normale
  • ***
  • Post: 158
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Vodafone Ideos, Nexus 5
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #8 il: 18 Luglio 2013, 18:01:58 CEST »
0
Davvero ottimo tutorial, mi ha aiutato tantissimo.

Ho una domanda:
Ho implementato la action bar(molto semplice, home button e titolo) direttamente nel fragment, ma se provo a cliccare su home non succede nulla.Se invece dichiaro la actionbar come nel tuo esempio funziona, ma ho notato che la home viene lanciata dall'activity(e so che cosí che deve funzionare).
Il mio problema é che ho un database aperto nel fragment e voglio chiuderlo quando home viene cliccato. Il metodo onOptionItemSelected non viene invocato nel fragment.

Codice (Java): [Seleziona]
 @Override
     public boolean onOptionsItemSelected(MenuItem item) {
             switch (item.getItemId()) {
             case R.id.homeAsUp:
                 Log.i("","Fragment");
                 getActivity().finish();
                 db.close;
                 return true;

             }
             return super.onOptionsItemSelected(item);
     }

Avete qualche suggerimento a riguardo?

Offline Trigun

  • Utente normale
  • ***
  • Post: 183
  • Respect: +4
    • Mostra profilo
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #9 il: 18 Luglio 2013, 18:33:59 CEST »
0
fai un metodo pubblico per chiudere il db?
non vedo il problema ...

Offline dom4

  • Utente normale
  • ***
  • Post: 158
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Vodafone Ideos, Nexus 5
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #10 il: 18 Luglio 2013, 20:39:01 CEST »
0
fai un metodo pubblico per chiudere il db?
non vedo il problema ...

Io ho CasaActivity e CasaFragment.
Dichiaro la actionbar in CasaFragment ma se clicco il tasto back/home il metodo onOptionItemSelected non viene invocato.
Se dichiaro onOptionItemSelected in CasaActivity funziona.
Ma in CasaFragment ho un db aperto e se non lo chiudo potrei avere problemi di leaking.
Uso db.close().

Offline Trigun

  • Utente normale
  • ***
  • Post: 183
  • Respect: +4
    • Mostra profilo
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #11 il: 18 Luglio 2013, 20:43:59 CEST »
0
continuo a ripetere....
CasaFragment.chiudiDb()

non vedo il problema...
oppure semplicemente usa onClose()

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #12 il: 19 Luglio 2013, 00:01:29 CEST »
0
Io ho CasaActivity e CasaFragment.
Dichiaro la actionbar in CasaFragment ma se clicco il tasto back/home il metodo onOptionItemSelected non viene invocato.
Se dichiaro onOptionItemSelected in CasaActivity funziona.
Ma in CasaFragment ho un db aperto e se non lo chiudo potrei avere problemi di leaking.
Uso db.close().

Senza codice è un pò difficile rispondere.

Innanzitutto. Parliamo di Home o di back ? Sono due cose diverse.

Se parliamo di Home, nell'Activity
Codice (Java): [Seleziona]
  public boolean onOptionsItemSelected(MenuItem item) {
     .....
     return super.onOptionsItemSelected(item);
 }
sei sicuro di:
- non intercettare già l'evento
- di aver messo il super.onOnOptionsItemSelected(item) ?

il metodo nella activity viene eseguito prima di quello del Fragment.

Altra verifica.
Il metodo nel Fragment non viene chiamato solo per l'home, o anche per tutti gli altri item?

Offline dom4

  • Utente normale
  • ***
  • Post: 158
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Vodafone Ideos, Nexus 5
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #13 il: 19 Luglio 2013, 09:59:35 CEST »
0
Grazie GabMarioPower.
Vorrei implementare il back.

Ecco un pó di codice
Fragment

Codice (Java): [Seleziona]
public class CasaFragment extends SherlockFragment {

         private Button bImmigration,bOrientation,bServiceApartment,bHomeSearch,bLeaseTermination,bShipment;
         private Intent intent;
         private DataBaseCasa db;
       
        private Cursor cImmigration;
         
         @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container,
              Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.relocation_details_fragment,
                container, false);
           
            ActionBar actionBar =  ((SherlockFragmentActivity) getActivity()).getSupportActionBar();
           
            actionBar.setTitle(R.string.relocation_details);
            actionBar.setIcon(R.drawable.ic_navigation_previous_item);
            actionBar.setHomeButtonEnabled(true);
//        actionBar.setDisplayHomeAsUpEnabled(true);
       
          db = new DataBaseCasa(getActivity());
            db.open();
           
          //Get current date
                   
            cImmigration = db.getTable("immigration");
            cImmigration.moveToFirst();
           
            String appReceive = cImmigration.getString(cImmigration.getColumnIndex("application_receive_data"));
           
            bImmigration = (Button) view.findViewById(R.id.buttonImmigration);
            bOrientation = (Button) view.findViewById(R.id.buttonOrientation);
            bServiceApartment = (Button) view.findViewById(R.id.buttonServiceApartment);
            bHomeSearch = (Button) view.findViewById(R.id.buttonHomeSearch);
            bLeaseTermination = (Button) view.findViewById(R.id.buttonLeaseTermination);
            bShipment = (Button) view.findViewById(R.id.buttonShipment);
           
            bImmigration.setOnClickListener(new OnClickListener() {
                       
                        @Override
                        public void onClick(View v) {
                                // TODO Auto-generated method stub
                                intent = new Intent(getActivity(), ImmigrationActivity.class);
                                intent.putExtra("request",appReceive);
                                startActivity(intent);
                        }
                });
           
            bOrientation.setOnClickListener(new OnClickListener() {
                       
                        @Override
                        public void onClick(View v) {
                                // TODO Auto-generated method stub
                                intent = new Intent(getActivity(), OrientationActivity.class);
                                startActivity(intent);
                        }
                });
           
            bServiceApartment.setOnClickListener(new OnClickListener() {
                       
                        @Override
                        public void onClick(View v) {
                                // TODO Auto-generated method stub
                                intent = new Intent(getActivity(), ServiceApartmentActivity.class);
                                startActivity(intent);
                        }
                });
           
            bHomeSearch.setOnClickListener(new OnClickListener() {
       
                @Override
                public void onClick(View v) {
                        // TODO Auto-generated method stub
                        intent = new Intent(getActivity(), HomeSearchActivity.class);
                        startActivity(intent);
                }
            });
            bLeaseTermination.setOnClickListener(new OnClickListener() {
       
                @Override
                public void onClick(View v) {
                        // TODO Auto-generated method stub
                        intent = new Intent(getActivity(), LeaseTerminationActivity.class);
                        startActivity(intent);
                }
            });
            bShipment.setOnClickListener(new OnClickListener() {
       
                        @Override
                        public void onClick(View v) {
                                // TODO Auto-generated method stub
                                intent = new Intent(getActivity(), ShipmentActivity.class);
                                startActivity(intent);
                        }
            });

           
            return view;
         }
          @Override
     public boolean onOptionsItemSelected(MenuItem item) {
             switch (item.getItemId()) {
             case R.id.homeAsUp:
                 Log.i("","Fragment");
                 getActivity().finish();
                 return true;

             }
             return super.onOptionsItemSelected(item);
     }
       
        }

Activity

Codice (Java): [Seleziona]
public class CasaActivity extends SherlockFragmentActivity {
       
       
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.relocation_details_activity);
        }
       
          @Override
             public boolean onOptionsItemSelected(MenuItem item) {
                     switch (item.getItemId()) {
                     case R.id.homeAsUp:
                         Log.i("","Called in Activity");
                         this.finish();
                         db.close();
                         cImmigration.close();
                         return true;

                     }
                     return super.onOptionsItemSelected(item);
             }
}

onOptionItemSelected non viene mai invocato nel fragment solo nell'activity.
« Ultima modifica: 19 Luglio 2013, 10:25:10 CEST da dom4 »

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:Utlizzo dei Menu con Action Bar , Fragment e SherlockActionBar
« Risposta #14 il: 19 Luglio 2013, 16:21:52 CEST »
0
Citazione
Codice (Java): [Seleziona]
public class CasaActivity extends SherlockFragmentActivity {
       
       
          @Override
             public boolean onOptionsItemSelected(MenuItem item) {
                     switch (item.getItemId()) {
                     case R.id.homeAsUp:
                         Log.i("","Called in Activity");
                         this.finish();
                         db.close();
                         cImmigration.close();
                         return true;

                     }
                     return super.onOptionsItemSelected(item);
             }
}

onOptionItemSelected non viene mai invocato nel fragment solo nell'activity.

Perchè case R.id.homeAsUp: viene intercettato dall'activity.