Autore Topic: [facile] Uso dei Menu  (Letto 17347 volte)

Offline maku85

  • Nuovo arrivato
  • *
  • Post: 28
  • Respect: +35
    • Mostra profilo
  • Dispositivo Android:
    Sony Xperia J
  • Play Store ID:
    MaKu
  • Sistema operativo:
    Windows 8.1
[facile] Uso dei Menu
« il: 03 Giugno 2011, 15:03:37 CEST »
+6
Livello di difficoltà: facile
Link al file compresso del progetto eclipse: file in allegato

Cosa sono i menu lo sappiamo tutti visto che ne abbiamo sempre a che fare con i computer o i cellulari quindi passiamo direttamente a definire quali sono i menu previsti da Android.
In Android esistono tre differenti tipi di menu che lo sviluppatore può collegare ad una Activity e sono:
1) Options Menu
cioè i menu nati per raggruppare le opzioni e i comandi di un'applicazione che a loro volta si dividono in due sottogruppi:
          1a) Icon Menu
            che sono i menu con le opzioni principali di un'applicazione.Vengono             visualizzati nella parte bassa dello schermo quando si schiaccia il tasto "MENU" del dispositivo. Si    chiamano "icon" perchè gli elementi contenuti al loro interno di solito sono delle grosse icone che l'utente può selezionare. Costituiscono il menu principale di ogni attività e dovrebbero contenere solo le opzioni più importanti. Sono di rapido acceso ma hanno di negativo il fatto che possono contenere al massimo sei elementi e non è possibile inserire elementi avanzati come checkbox o bottoni radio.
          1b) Expanded Menu
            che si utilizzano quando gli Icon Menu non sono sufficienti a esporre tutti i comandi e le opzioni di un'applicazione. Quando ciò avviene nel menu principale sarà presente come ultimo tasto il bottone Altro che attivato fa accedere ad una lista a tutto schermo delle altre opzioni di menu.
2) Context Menu
sono i menu contestuali cioè quelli che appaioni quando si mantiene il tocco per qualche istante su qualche widget che ne è dotato. Quando attivato si presenta come una lista a tutto schermo che può contenere numerose opzioni.
3) Submenu
sono utili per le applicazioni che dispongono di molti comandi. In pratica da la possibilità di inserire, in uno dei menu definiti prima, un elemento che anzichè compiere un'attività diretta va ad aprire un sottomenu nel quale si possono presentare ulteriori possibilità di scelta.

Iniziamo quindi a definirli uno per volta.

Options Menu
Ogni activity può avere un solo Options Menu. La classe utilizzata è onCreateOptionsMenu(Menu menu) che nel ciclo di vita dell'attività viene richiamato automaticamente dal sistema la prima volta che l'utente preme il tasto "MENU" del dispositivo. L'argomento passato è un oggetto di tipo android.view.Menu ed è il menu inizialmente vuoto. Ridefinendo il metodo lo si può popolare con le voci utili della propria applicazione. Il metodo dopo aver svolto i proprio compiti restituisce un booleano:true per rendere attivo il menu realizzato, false per dichiarare che l'attività non dispone di un menu. Per aggiungere un elemento basta usare uno dei due metodi: add(CharSequence title) o add(int titleRes). Entambi aggiungono un elemento al menu passandogli come argomento il titolo che vogliamo inserirgli, nel primo caso il titolo dell'elemento viene passato come stringa, nel secondo caso come riferimento ad una risorsa di tipo stringa mermorizzata su file XML esterno. Più in dettaglio è possibile usare anche i metodo add(int groupId, int itemId, int order, CharSequence title) o add(int groupId, int itemId, int order, int titleRes) dove oltre al titolo è possibile specificare altre tre prorprietà, cioè:
- groupId
con cui è possibile assegnare l'elemento ad un gruppo. Si può specificare un qualsiasi valore maggiore di zero (ovviamente deve essere lo stesso per gli elementi che appartengono allo stesso gruppo) oppure si può usare lo zero o la costante Menu.NONE se non si vuole assegnare l'elemento a nessun gruppo.
-itemId
con cui si assegna un identificativo all'elemento, utile quando si vuole distinguere un elemento da un altro. Bisogna sempre usare un numero maggiore di zero  per sfruttare la caratteristica oppure zero o Menu.NONE per ignorarla.
-order
con cui si assegna uno specifico ordine all'elemento nel menu. In questo caso lo si specifica esplicitamente con un valore da un o in su. Come al solito con zero o la costante Menu.NONE si ignora l'opziona lasciando stabilire al sistema l'ordine dell'elemento nel menu di appartenenza.

Ad esempio per creare un semplice menu con 6 opzioni:
Codice (Java): [Seleziona]
@Override
public boolean onCreateOptionsMenu(Menu menu) {
        menu.add("Comando 1");
        menu.add("Comando 2");
        menu.add("Comando 3");
        menu.add("Comando 4");
        menu.add("Comando 5");
        menu.add("Comando 6");
        return true;
}



Se invece adesso ne aggiungiamo 9 le cose cambiano, il sistema pone i primi cinque come Icon Menu e il sesto spazio viene occupato da un elemento di tipo "Altro" che funziona come pulsante d'accesso all'Expanded Menu dell'attività e in quest'ultimo vengono inseriti i restanti quattro comandi.

 

Gli elementi che confluiscono nell'Icon Menu possono utilizzare delle icone al posto del testo. Per farlo basta applicare all'oggetto di tipo android.view.MenuItem che ci viene restituito dal metodo add() il metodo setIcon() passandogli un oggetto di tipo graphics.drawable.Drawable caricato o realizzato in precedenza o il riferimento ad un'immagine conservata nella directory res/drawable.
(Attenzione però, se l'elemento non è parte dell'Icon Menu l'icona non verrà mostrata).

Passiamo ora alla gestione degli eventi di attivazione di ciascun elemento. Esistono un paio di maniere per intercettare gli eventi di tocco riscontrati sugli elementi di un Options Menu. La prima tecnica consiste nel ridefinire il metodo onOptionsItemSelected(MenuItem Item) che viene richiamato automaticamente ogni volta che uno degli elementi dell'Options Menu dell'attività viene selezionato dall'utente. Lo specifico elemento è naturalmente quello riportato in argomento al metodo mentre il valore di ritorno è un booleano che vale true se l'evento è stato gestito oppure false se no. Ridefinendo il metodo e applicando dei filtri sull'identificativo dell'elemento (recuperabile con il metodo getId()) è possibile riconoscere e gestire la specifica azione eseguita dall'utente.
Ad esempio possiamo fare in modo che quando viene selezionata un'opzione dal menu venga mostrato un toast con il titolo dell'elemento:
Codice (Java): [Seleziona]
static final int COMANDO1 = 0;
        static final int COMANDO2 = 1;
        static final int COMANDO3 = 2;
...
@Override
    public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
      case 0:
          Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
        return true;
      case 1:
          Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
        return true;
      case 2:
          Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
        return true;
      default:
        return super.onOptionsItemSelected(item);
      }
    }

Una tecnica consigliata è quella di memorizzare gli identificativi degli elementi del menu con delle costanti per renderli più leggibili ed evitare errori di battitura o distrazioni. Una seconda tecnica consiste nell'utilizzare su ogni menu item il metodo
setOnMenuItemClickListener(MenuItem.onMenuItemClickListenermenuItemClickListener) (simile al caso delle dialog dove si utilizzava il metodo DialogInterface.onClickListener()). L'interfaccia MenuItem.OnMenuItemClickListener richiede l'implementazione del metodo
onMenuItemClick(MenuItem item). Il metodo viene richiamato quando l'elemento è selezionato dall'utente.
Esempio:
Codice (Java): [Seleziona]
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add("Comando1").setOnMenuItemClickListener(new OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                        Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
                        return true;
                }
        });;
        menu.add("Comando2").setOnMenuItemClickListener(new OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                        Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
                        return true;
                }
        });;
        menu.add("Comando3").setOnMenuItemClickListener(new OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                        Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
                        return true;
                }
        });;
        return true;
    }

Per quanto riguarda la gestione dell'Options Menu ci sono altri metodi come:
- onPreparedOptionsMenu(Menu menu) che viene richiamato quando il menu sta per essere visualizzato. Infatti il metodo precedente, onCreateOptionsMenu(), viene richiamato solo la prima volta che il menu deve essere mostrato. Se si vuole modificare il menu costruito in precedenze si può ridefinire questo secondo metodo. A questo proposito gli oggetti Menu dispongono di una serie di metodi per recuperare, modificare e rimuovere gli elementi introdotti al suo interno in precedenza.
- onOptionsMenuClosed(Menu menu) richiamato quando il menu dopo essere stato visualizzato viene chiuso.
- openOptionsMenu() che apre il menu automaticamente senza che il tasto MENU del dispositivo venga premuto.

Context Menu
Come già detto i Menu Contestuali permettono di associare particolari opzioni o comandi ai singoli widget di un'attività. La creazione e utilizzo sono molto simili a quelli dell'Options Menu.
Bisogna prima dichiarare che uno o più widget dell'attività devono disporre di un menu contestuale con il metodo registerForContextMenu(View view).
Ad esempio per dare un menu ad un bottone:
Codice (Java): [Seleziona]
Button mioBottone=new Botton(this);
...
registerForContextMenu(mioBottone);

se invece il widget è stato dichiarato un un XML di layout lo si puo caricare attraverso il suo id:
Codice (Java): [Seleziona]
View mioWIdget=findById(R.id.mioWidgetId);
...
registerForContextMenu(mioWidget);

Fatto questo è possibile ridefinire uno o più metodi per gestire il menu, come:
- onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) che viene richiamato ogni volta che il menu contestuale per il widget "v" deve essere mostrato. Il menu deve essere costruito aggiungendo elementi al parametro "menu". Il terzo argomento "menuInfo" si usa solo in alcuni casi(ad esempio quando si ha a che fare con le liste).
Esempio:
Codice (Java): [Seleziona]
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        menu.add("Comando1");
        menu.add("Comando2");
        menu.add("Comando3");
    }



- onContextItemSelected(MenuItem item) richiamato quando un elemento del menu viene selezionato.
Ad esempio:
Codice (Java): [Seleziona]
    @Override
    public boolean onContextItemSelected(MenuItem item) {
      switch (item.getItemId()) {
      case 0:
          Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
        return true;
      case 1:
          Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
        return true;
      case 2:
          Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
        return true;
      default:
        return super.onContextItemSelected(item);
      }
    }

Anche nel caso di Context Menu è possibile sfruttare la tecnica di gestione alternativa con onMenuItemClickListener.

- onContextMenuClose(Menu menu) richiamato quando il menu viene chiuso. I Menu Contestuali dispongono di tutti i metodi già visti con gli oggetti Menu a parte la possibilità di supportare icone e scorciatoie da tastiera. In compenso gli oggetti Context Menu si specializzano attraverso i seguenti metodi che permettono di personalizzare l'intestazione del menu:
- setHeaderTitle(CharSequence title) o setHeaderTitle(int titleRes) che associano un titolo al Menu Contestuale che sarà mostrato nell'intestazione del menu.
- setHeaderIcon(Drawable icon) o setHeaderIcon(int IconRes) che associano un'icona al menu contestuale mostrato nell'intestazione del menu.
- setHeaderView(View view) che impostano l'oggetto "view" come intestazione del meno sostituendo l'icona ed il titolo dei metodi precedenti.
- clearHeader() che ripulisce l'intestazione del menu.

Submenu
Per aggiungere Sotto-Menu ad un Options Menu o ad un Context Menu si usano i seguenti metodi:
-addSubMenu(CharSequence title), addSubMenu(int titleRes), addSubMenu(int groupId, int itemId, int order, CharSequence title) e addSubMenu(int groupId, int itemId, int order, int titleRes).
Per stabilire cosa viene mostrato quando si seleziona un Sotto Menu si utilizza l'oggetto android.view.SubMenu restituito dai metodi addSubMenu(). Anche in questo caso si avranno a disposizione tutti  i metodi di Menu e anche alcuni di quelli dei Context Menu per la definizione di un'intestazione.
Esempio:
Codice (Java): [Seleziona]
    public boolean  onCreateOptionsMenu(Menu menu) {
        menu.add("Comando1");
        menu.add("Comando2");
        menu.add("Comando3");
        SubMenu submenu = menu.addSubMenu("Altri comandi");
        submenu.add("Comando4");
        submenu.add("Comando5");
        submenu.add("Comando6");
        return true;
    }



Altre caratteristiche dei menu

Gruppi di elementi
Gli elementi di un menu,come anticipato prima, possono essere riuniti in dei gruppi. Due o più elementi sono nello stesso gruppo se quando li si è aggiunti si è usato lo stesso valore di "groupId". I gruppi di elementi permettono di velocizzare  alcune operazioni, ad esempio:
- si possono abilitare e disabilitare tutti gli elementi di un gruppo con un solo metodo setGroupEnabled(int groupId, boolean enabled),
- renderli visibili o invisibile con il metodo setGroupVisible(int groupId, boolean visile),
- rendere checkable tutti gli elementi del gruppo con il metodo setGroupCheckable(int groupId, boolean checkable, boolean exclusive) (se il terzo argomento e "false" tutti gli elementi si comportano come delle checkbox, cioè è possibile selezionare anche due o più elementi contemporaneamente, se invece è "true" gli elementi si comporteranno come dei bottoni radio, cioè sarà possibile selezionarne solo uno per volta). Un elemento si può selezionare o deselezionare con il metodo setChecked(booelan checked) e per sapere se un elemento eè selezionato o menu si utilizza isChecked()

Menu in XML
I menu come i layout possono essere definiti via XML. Per farlo si usa la speciale cartella res/menu. I file XML al suo interno usano i tag <menu>, <group> e <item> per definire i menu in modo dichiarativo. I menu XML possono essere caricati attraverso la classe android.View.Inflater ed il suo metodo inflate(int MenuRes, Menu menu).
Esempio di un menu xml:
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@+id/item1"
                android:icon="@drawable/item1"
                android:title="@string/item1"/>
        <!-- menu group -->
        <group android:id="@+id/group1">
                <item android:id="@+id/groupItem1"
                        android:title="@string/groupItem1"/>
                <item android:id="@+id/groupItem2"
                        android:title="@string/groupItem2"/>
        </group>
</menu>

e il suo utilizzo nell'applicazione
Codice (Java): [Seleziona]
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

Esempio di menu xml con elementi checkable
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
        <group android:checkableBehavior="single">
                <item android:id="@+id/red"
                        android:title="@string/comando1"/>
                <item android:id="@+id/blue"
                        android:title="@string/comando2"/>
        </group>
</menu>

Gli attributi accettati da android:checkableBehavior sono:
- single per creare dei radio button
- all per creare delle checkbox
- none per non renderli checkable

Si può selezionare un item checked di default tramite l'attributo android:checked nell'<item>. Quando un elemento checkable è selezionato il sistema richiama il suo rispettivo metodo (ad esmpio onOptionsItemSelected) ed è qui che si può impostare se un elemento è selezionato o meno perchè un checkbox o un radio button non cambiano il loro stato automaticamente. Si può verificare se è selezionato con il metodo isChecked()ed eventualmente cambiarlo con il metodo setChecked()

Scorciatoie di tastiera
Quando l'utente è in posseso di un dispositivo con tastiera fisica gli si può dare la possiblità di selezionare gli elementi  del menu con delle scorciatoie composte da lettere o numeri utilizzando nell'elemento <item> l'attributo android:alphabeticShortcut e android:numericShortcut o altriimenti utilizzando nel codice i metodi setAlphabeticShortcut(char) e setNumericShortcut(char). Le scorciatoie non sono case sensitive (non c'è distinzione tra "a" e "A") e non sono utilizzabili per gli elementi dei Context Menu.

Aggiunta dinamica di menu intent
A volte c'è bisogno di far si che un elemento del menu lanci un intent. Nel caso in cui si conosce già l'intent da utilizzare basta usare il metodo startActivity() quando viene selezionato l'elemento interessato. Ma se non si è certi che il dispositivo dell'utente contiene un'applicazione che possa gestire quell'intent si rischia di creare un elemento del menu non funzionante. Per risolvere questo problema Android fornisce la possibilità di aggiungere dinamicamente gli elementi del menu se presenti nel dispositivo applicazioni che possano gestire quell'intent.
Per farlo bisogna:
- definire un intent con la categoria CATEGORY_ALTERNATIVE e/o CATEGORY_SELECTED_ALTERNATIVE(usato quando per gestire l'elemento attualmente selezionato sullo schermo, quando si crea un menu con il metodo onCreateContextMenu()) più altr requisiti,
- chiamare il metodo Menu.addIntentOptions(). Android quindi cercherà l'applicazione che potrà gestire l'intent ed eventualmente la aggiugnera al nostro menu (in caso contrario non aggiungerà niente).
Ad esempio:
Codice (Java): [Seleziona]
@Override
public boolean onCreateOptionsMenu(Menu menu){
        super.onCreateOptionsMenu(menu);
        Intent intent = new Intent(null, dataUri);
        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
        menu.addIntentOptions(R.id.intent_group, 0, 0, this.getComponentName(), null, intent, 0, null);  
        return true;
}

per ogni applicazione che soddisfa il requisito verrà creato un elemento del menu. Il metodo addIntentOptions() da come risultato il numero di elementi aggiunti.

Permettere alla propria attività di essere aggiunta ad altri menu
Con il meccanismo spiegato precedentemente è possibile permettere che la propria attività venga aggiunta dinamicamente nei menu di altre applicazioni se richiesto. Per farlo basta aggiungere il valore CATEGORY_ALTERNATIVE o CATEGORY_SELECTED_ALTERNATIVE nella categoria degli intent-filter
Per esempio:
Codice (XML): [Seleziona]
<intent-filter label="Resize Image">
...
<category android:name="android.intent.category.ALTERNATIVE"/>
<category android:name="android.intent.category.SELECTED_ALTERNATIVE"/>
 ...
</intent-filter>


Sorgenti:
Bibliografia:
« Ultima modifica: 03 Giugno 2011, 15:07:50 CEST da maku85 »
- Il programmatore è colui che risolve in un modo incomprensibile un problema che non sapevi di avere -

Offline JD

  • Amministratore
  • Utente storico
  • *****
  • Post: 1600
  • Respect: +232
    • leinardi
    • Mostra profilo
  • Dispositivo Android:
    LG Nexus 5
  • Sistema operativo:
    L'ultima Ubuntu
Re:[facile] Uso dei Menu
« Risposta #1 il: 03 Giugno 2011, 20:49:25 CEST »
0
Grazie

Hai pubblicato un altro tutorial a regola d'arte :)
È stata trovata una soluzione al tuo problema?
Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato ;).
E se hai aperto tu il thread marcalo come risolto cliccando !

Offline ROS

  • Utente normale
  • ***
  • Post: 196
  • Respect: +5
    • Mostra profilo
  • Sistema operativo:
    Ubuntu 10.04
Re:[facile] Uso dei Menu
« Risposta #2 il: 03 Agosto 2011, 15:19:58 CEST »
0
[cancellato]

Offline yoshi

  • Nuovo arrivato
  • *
  • Post: 30
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    LG Optimu Black (P970)
  • Sistema operativo:
    Mac OS X 10.7
Re:[facile] Uso dei Menu
« Risposta #3 il: 18 Febbraio 2012, 12:36:25 CET »
0
scusate ma se volessi che il mio optionmenu mettesse una voce per ogni riga come devo fare?  :-)

Offline Nexus19

  • Nuovo arrivato
  • *
  • Post: 44
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus, Nexus 7
  • Sistema operativo:
    Windows 8
Re:[facile] Uso dei Menu
« Risposta #4 il: 25 Gennaio 2013, 19:56:21 CET »
0
Ho creato un menù laterale, ora vorrei collegare la voce nel menù ad un "linK" con una query cioè deve portarmi quell'item a una pagina con i dati che si trovano nel mio db..come faccio? ho già creato la query

Offline Giamme

  • Nuovo arrivato
  • *
  • Post: 43
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic
  • Play Store ID:
    appLOOPiamo
  • Sistema operativo:
    Windows 7
Re:[facile] Uso dei Menu
« Risposta #5 il: 12 Marzo 2013, 11:32:41 CET »
0
Grazie mille, tutorial bello completo.
"Tutto ciò che è necessario per il trionfo del male è che gli uomini buoni non facciano nulla."
Edmund Burke