T#017 – Creare e gestire i menu delle applicazioni Android

Eccoci con un nuovo tutorial di programmazione Android, oggi parleremo di un argomento interessante. Gli smartphone Android, come sicuramente saprete, hanno sempre almeno tre tasti fisici, il tasto back (simile a quello dei browser) il tasto home che permette di tornare alla home di Android e il tasto menù. Oggi parleremo proprio di quest’ultimo e vedremo come gestire il tasto menu che, come facilmente avrete intuito, alla sua pressione mostra un menu contestuale nella parte bassa del display.

Iniziamo con un semplice esempio di una applicazione Android, l’unica activity del progetto contiene 3 button. Il layout è il seguente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal" android:layout_width="fill_parent"
	android:layout_height="fill_parent" android:gravity="center">
	<Button android:id="@+id/button1" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:text="@string/button1"
		android:onClick="onClickButton" />
	<Button android:id="@+id/button2" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:text="@string/button2"
		android:onClick="onClickButton" />
	<Button android:id="@+id/button3" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:text="@string/button3"
		android:onClick="onClickButton" />
</LinearLayout>

L’activity è molto semplice, l’unica cosa da notare è il metodo invocato sull’onClick dei button che disabilita il button chiamante:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MainActivity extends Activity
{
	private View button1;
	private View button2;
	private View button3;
 
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		button1 = findViewById(R.id.button1);
		button2 = findViewById(R.id.button2);
		button3 = findViewById(R.id.button3);
	}
 
	public void onClickButton(View v)
	{
		v.setEnabled(false);
	}
}

Usando questa splendida interfaccia possiamo cliccare una volta sola su ogni button, infatti dopo il primo click il button viene disabilitato e i successivi click sono quindi ignorati. Per far durare di più il divertimento (perchè giocare a fruit ninja quando si può cliccare su ben tre button? :)) vogliamo aggiungere delle voci di menu che permettono di abilitare i tre button presenti nel layout.

Definire un menu nelle applicazioni Android

Per prima cosa definiamo il menu che vogliamo mostrare, come per i layout i menu possono essere definiti in un file xml o creati dinamicamente usando codice java. Creiamo il nostro primo menu in un file xml chiamato menu.xml all’interno della directory res/menu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:id="@+id/menu_add" android:title="@string/enable"
			android:icon="@android:drawable/ic_menu_edit">
		<menu>
			<item android:id="@+id/enable_button_1"
				android:title="@string/button1" />
			<item android:id="@+id/enable_button_2"
				android:title="@string/button2" />
			<item android:id="@+id/enable_button_3"
				android:title="@string/button3" />
		</menu>
	</item>
	<item android:id="@+id/menu_about" android:title="@string/about"
		android:icon="@android:drawable/ic_menu_info_details" />
</menu>

In questo file abbiamo creato un menu composto da due voci di menu, la prima contiene a sua volta un sottomenu con tre elementi mentre la seconda non ha sottomenu. Come sempre le stringhe sono definite nel file strings.xml e le icone sono prese fra quelle standard di Android utilizzando la sintassi @android:drawable/. Se avete installata l’ultima versione del plugin Android per Eclipse avrete l’autocomplete che aiuta molto nella scrittura di questi file xml (ctrl+spazio per attivarlo).

Ok, abbiamo il nostro menu pronto per essere usanto, ma ancora non l’abbiamo inserito all’interno dell’activity.Facciamolo! Il metodo giusto della classe Activity da sovrascrivere è:

onCreateOptionsMenu:

1
2
3
4
5
public boolean onCreateOptionsMenu(Menu menu)
{
	getMenuInflater().inflate(R.menu.menu, menu);
	return true;
}

In questo metodo abbiamo semplicemente eseguito l’inflate del menu e ritornato true per indicare che vogliamo che il nostro menu sia mostrato. Con il termine inflate si indica il processo di creazione o popolamento di un oggetto java (in questo caso un menu, ma il termine viene usato anche per i layout) partendo da un file xml.

Il risultato è il seguente:



Cliccando su Enable viene mostrato il sottomenu:



Gestione del click sui menu

Abbiamo creato il menu ma ancora non abbiamo gestito il click sulle singole voci. Per associare del codice java a ogni voce di menu è possibile riscrivere il metodo onOptionsItemSelected in questo modo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public boolean onOptionsItemSelected(MenuItem item)
{
	switch (item.getItemId())
	{
	case R.id.enable_button_1:
		button1.setEnabled(true);
		return true;
	case R.id.enable_button_2:
		button2.setEnabled(true);
		return true;
	case R.id.enable_button_3:
		button3.setEnabled(true);
		return true;
	case R.id.menu_about:
		Toast.makeText(this, R.string.about_clicked, 
			Toast.LENGTH_LONG).show();
		return true;
	}
	return super.onOptionsItemSelected(item);
}

Questo metodo contiene solitamente un blocco switch con un case per ogni voce di menu definita. Nel nostro caso la logica da implementare è molto semplice, nei primi tre rami dello switch abilitiamo il corrispondente button nell’ultimo mostriamo semplicemente un messaggio. Questo metodo ritorna true per indicare che il click è stato gestito.

Abilitazione dei menu

Il metodo onCreateOptionsMenu viene invocato solo la prima volta che viene mostrato un menu, alle successive pressioni del tasto menu viene riusato il menu creato in precedenza. Ma cosa dobbiamo fare se vogliamo disabilitare una voce di menu a seconda di una condizione che cambia di volta in volta? Nel nostro esempio non vogliamo che sia abilitata una voce di menu se il button corrispondente è già abilitato.

Per fare questo riscriviamo il metodo onPrepareOptionsMenu che viene richiamato ogni volta che viene premuto il tasto menu:

1
2
3
4
5
6
7
8
9
10
public boolean onPrepareOptionsMenu(Menu menu)
{
	menu.findItem(R.id.enable_button_1).setEnabled(
		!button1.isEnabled());
	menu.findItem(R.id.enable_button_2).setEnabled(
		!button2.isEnabled());
	menu.findItem(R.id.enable_button_3).setEnabled(
		!button3.isEnabled());
	return true;
}

In questo metodo abilitiamo le tre voci di menu in base all’attributo enabled del corrispondente button.

Conclusioni

Finisce qui questo post sui menu di Android, come sempre i sorgenti dell’esempio completo sono disponibili per il download. Tutto quello detto in questo post è valido per lo sviluppo sugli smartphone, per i tablet i concetti principali rimangono inalterati, ma cambiano un paio di cose. Ma di sviluppo sui tablet Android avremo modo di approfondire in futuro!

By Fabio Collini

Da agosto 2009 sono un freelance android developer, ho rilasciato due applicazioni nell'Android Market: Apps Organizer e Folder Organizer. Presso OmniaGroup ricopro il ruolo di Tech Leader nell'ambito di un progetto di rich internet application che utilizza JSF, JPA(EclipseLink) ed EJB3.

1 comment

Leave a comment

Your email address will not be published.