Negli esempi visti nei precedenti tutorial abbiamo sempre usato interfacce Android composte solo da activity contenenti tutti i componenti da visualizzare. Ovviamente Android mette a disposizione vari metodi per notificare l’utente e per mostrare finestre di dialogo che coprono solo in parte l’activity principale. In questo post vedremo un semplice esempio in cui mostreremo all’opera i vari metodi disponibili.
Iniziamo subito con il nostro primo esempio, che sarà composto da una sola activity che contiene tre button associati a tre metodi all’interno dell’activity stessa:
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="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dip" android:text="@string/toast" android:onClick="createToast" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dip" android:text="@string/about" android:onClick="openAbout" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dip" android:text="@string/cambia_titolo" android:onClick="changeTitle" /> </LinearLayout> |
Il risultato non è proprio bello da vedere ma è comunque utile per spiegare alcuni concetti!
La class Toast
Il modo più semplice per mostrare un messaggio non bloccante all’utente in Android è attraverso la classe Toast (eviterò di fare battute di basso livello sul nome di questa classe! :)). Il seguente metodo, associato al primo button dell’activity, mostra un messaggio che scompare in automatico dopo alcuni secondi:
1 2 3 4 | public void createToast(View v) { Toast.makeText(this, getTitle(), Toast.LENGTH_LONG).show(); } |
Il metodo makeText accetta tre parametri in ingresso:
- il classico Context che solitamente viene valorizzato con l’activity corrente
- il testo da mostrare, in questo caso viene mostrato il titolo dell’activity
- la durata della notifica, possono essere usate le due costanti LENGTH_LONG e LENGTH_SHORT della classe Toast
Una volta creato il Toast può essere mostrato usando il metodo show. In una riga di codice abbiamo creato una notifica poco invasiva ma che può essere utile in molti contesti:
Finestre di dialogo su Android
Vediamo un esempio un po’ più complesso in cui creiamo un dialog Android, nello specifico creeremo una finestra di dialogo che mostrerà le informazioni della nostra applicazione (il classico “about”). Per fare questo, nel metodo associato al secondo button dell’activity, richiamiamo il metodo showDialog della classe Activity (il parametro passato è una costante definita nella classe):
1 2 3 4 5 6 | private static final int ABOUT_DIALOG = 1; public void openAbout(View v) { showDialog(ABOUT_DIALOG); } |
Richiamando questo metodo stiamo appunto dicendo che vogliamo che il nostro dialog venga mostrato, ovviamente questo non sarà sufficiente, dovremo infatti definire anche il metodo onCreateDialog che permetterà di creare il dialog associato all’id passato:
1 2 3 4 5 6 7 8 9 10 11 | protected Dialog onCreateDialog(int id) { switch (id) { case CHANGE_TITLE_DIALOG: return createChangeTitleDialog(); case ABOUT_DIALOG: return createAboutDialog(); } return null; } |
Solitamente questo metodo contiene un blocco switch con un case per ogni possibile dialog, che può essere mostrato nell’activity. Il metodo che crea realmente il dialog di about è il seguente:
1 2 3 4 5 6 7 | private AlertDialog createAboutDialog() { String message = "Sito web: <a href='http://android.devapp.it'>android.devapp.it</a><br>" + "Twitter: <a href='https://twitter.com/_devAPP'>@_devAPP</a>"; return new AlertDialog.Builder(this).setTitle("devAPP") .setMessage(Html.fromHtml(message)).create(); } |
In questo metodo abbiamo creato un’istanza di AlertDialog usando il corrispondente Builder. Questo modo di creare gli oggetti è un pattern consolidato in Java chiamato appunto builder. Invece di eseguire una new usiamo un’istanza builder e chiamiamo i setter su questo oggetto, quindi creiamo l’oggetto vero e proprio chiamando il metodo create.
1 2 3 4 | public void changeTitle(View v) { showDialog(CHANGE_TITLE_DIALOG); } |
Dialog più complesso
Il dialog di about è molto semplice, dopo tutto non contiene input nè button. Complichiamo ulteriormente le cose e vediamo un esempio più complesso. Vogliamo creare, questa volta, un dialog con un campo di input per modificare il title della nostra activity. Per impostare il body del dialog usiamo il metodo setView passando un’istanza di EditText (per ottenere layout più complessi avremmo potuto passare una qualunque View di Android). I due button in basso sono mostrati automaticamente se richiamiamo i metodi setPositiveButton e setNegativeButton. Questi due metodi prendono la label da mostrare nel button e un listener invocato sul click:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | private EditText titleText; private AlertDialog createChangeTitleDialog() { titleText = new EditText(this); return new AlertDialog.Builder(this) .setTitle(R.string.cambia_titolo).setView(titleText) .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { setTitle(titleText.getText()); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).create(); } |
Il risultato finale è questo:
Per ora abbiamo implementato solo il metodo onCreateDialog, che viene invocato solo la prima volta quando il dialog viene visualizzato. Ma come facciamo se vogliamo popolare un dialog con dati diversi ogni volta che viene mostrato? Possiamo riscrivere il metodo onPrepareDialog in questo modo:
1 2 3 4 5 6 7 8 | protected void onPrepareDialog(int id, Dialog dialog) { switch (id) { case CHANGE_TITLE_DIALOG: titleText.setText(getTitle()); } } |
Nel nostro caso abbiamo riscritto questo metodo per popolare il campo di input ogni volta che mostriamo il dialog. Quindi, in pratica, la prima volta che clicchiamo sul button vengono richiamati in sequenza i metodi onCreateDialog e onPrepareDialog, mentre ai click successivi viene richiamato solo il metodo onPrepareDialog, in modo tale da popolare il dialog già creato e visualizzato la prima volta.
Eccoci alla conclusione di questo nuovo tutorial di programmazione Android. Oggi abbiamo visto dei semplici esempi, ma ovviamente usando i dialog possiamo arrivare anche a sviluppare qualcosa di molto più complesso. I concetti necessari per creare un dialog non sono di per se complicati e i vari layout contenuti in un dialog sono sviluppati allo stesso modo in cui sono sviluppati i layout delle activity. Se volete consultare i sorgenti dell’esempio completo, come al solito, sono disponibili per il download al seguente indirizzo sottoforma di progetto Eclipse.