Per mostrare come realizzare una finestra di dialogo personalizzata utilizzerò una parte di codice presa da una delle mie applicazioni (Blind SMS Reader), apportando una piccola modifica per facilitarne la spiegazione che altrimenti si disperderebbe in altra argomentazione.
Una finestra di dialogo personalizzata (comunemente chiamata custom dialog o impropriamente anche popup) non è altro che una finestra di alert che viene mostrata in primo piano allo scatenarsi di un evento (che può semplicemente essere il clic su un bottone). La peculiarità di una finestra dialogo personalizzata è che, come dice il nome stesso, può essere realizzata a seconda delle proprie esigenze in termini di dimensioni ma soprattutto di contenuto dato che con essa sarà possibile gestire la presenza o meno della barra del titolo, personalizzare i bottoni al suo interno ed inserire anche delle immagini oltre al testo.
L'esempio che vado a mostrare esplica proprio le caratteristiche che ho appena elencato infatti la nostra dialog non avrà la barra del titolo e conterrà 3 immagini di cui una per la chiusura della stessa e altre due (che non vado a dettagliare) per le funzioni richieste dall'app. Non è presente nessun contenuto testuale ma la sua eventuale aggiunta comporterebbe semplicemente l'inserimento di una TextView nel layout della dialog.
La parte semplificata a livello di codice è il layout principale (main.xml) che ho volutamente modificare per lo scopo del presente articolo e che sarà composto da un testo e da un bottone che scaturirà l'apertura della nostra finestra di dialogo.
Di seguito il contenuto del file main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/textintro">
</TextView>
<Button
android:id="@+id/Button01"
android:layout_height="wrap_content"
android:layout_below="@+id/TextView01"
android:layout_width="wrap_content"
android:text="@string/textbutton">
</Button>
</RelativeLayout>
Il seguente codice invece rappresenta il layout della nostra finestra di dialogo personalizzata (mydialog.xml). Mi soffermo brevemente in quanto il contenuto del codice può sembrare leggermente complesso rispetto al suo risultato finale ma tale impostazione assicura che l'immagine per la chiusura della dialog (la X) si posizioni automaticamente in alto a destra della dialog stessa senza interferire con il resto dei componenti.
Nel codice sono presenti dei puntatori alle immagini utilizzate nella finestra di dialogo per cui per far sì che il codice di esempio vi funzioni dovrete inserire nella cartella drawable le varie immagini con il relativo nome.
Di seguito il contenuto del file mydialog.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ScrollView android:id="@+id/ScrollView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:text="@+id/TextView01"
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp" />
</ScrollView>
<LinearLayout
android:id="@+id/LinearLayoutButtonsRow01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ScrollView01"
android:weightSum="100">
<ImageButton android:id="@+id/DialogToCall01"
android:layout_height="0dp"
android:contentDescription="@string/textcall"
android:layout_marginTop="6dp"
android:layout_width="0dp"
android:layout_weight="50"
android:textSize="20sp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/dialog_call"
android:layout_marginRight="6dp" />
<ImageButton android:id="@+id/DialogReply01"
android:layout_height="0dp"
android:contentDescription="@string/textreply"
android:layout_marginTop="6dp"
android:layout_width="0dp"
android:layout_weight="50"
android:textSize="20sp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/dialog_reply" />
</LinearLayout>
<ImageView android:id="@+id/CloseDialogImageView"
android:contentDescription="@string/textclose"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/close_white"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true">
</ImageView>
</RelativeLayout>
Il codice per l'apertura della finestra di dialogo personalizzata è riportato di seguito ed è dovutamente commentato, presumo pertanto che essendo autoesplicativo non ci sia bisogno di aggiungere ulteriori spiegazioni, se così non fosse lasciateun commento all'articolo e sarò lieto di rispondervi:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Imposto il layout principale
setContentView(R.layout.main);
// Imposto il bottone che mostrerà la dialog
Button button01 = (Button) findViewById(R.id.Button01);
// Assegno l'apertura della dialog al click sul bottone
button01.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Inizializzo la mia dialog
Dialog dialog = new Dialog(MainActivity.this);
// Evito la presenza della barra del titolo nella mia dialog
dialog.getWindow();
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// Carico il layout della dialog al suo intenro
dialog.setContentView(R.layout.mydialog);
// Nel caso fosse previsto un titolo questo sarebbe il codice da
// utilizzare eliminando quello visto poco sopra per evitarlo
//dialog.setTitle("Testo per il titolo");
dialog.setCancelable(true);
// Qui potrei aggiungere eventuali altre impostazioni per la dialog
// ...
//Gestisco il bottone di chiusura della dialog (quello in alto a destra)
ImageView imgclose = (ImageView) dialog.findViewById(R.id.CloseDialogImageView);
imgclose.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dialog.dismiss();
}
});
//Gestisco il bottone, della dialog, di apertura della schermata per la chiamata
final ImageButton button_dialog_to_call = (ImageButton) dialog.findViewById(R.id.DialogToCall01);
button_dialog_to_call.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Funzioni varie
}
});
//Gestisco il bottone, della dialog, per l'apertura dell'applicazione nativa di messaggistica per rispondere all'SMS selezionato
final ImageButton button_dialog_reply = (ImageButton) dialog.findViewById(R.id.DialogReply01);
button_dialog_reply.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Funzioni varie
});
// Faccio comparire la dialog
dialog.show();
}
});
}
}
Di seguito, Fig. 1, la finestra di dialogo così come appena descritta:
Fig. 1 - Esempio di finestra di dialogo personalizzata (presente nell'app Blind SMS Reader)
Salve,
ho trovato l'articolo molto dettagliato e completo. Ma una cosa non ho riuscito a capire ed implementare nella mia applicazione, ovvero, lei ha creato un mydialog.xml contenente i bottoni della schermata dialog. Poi il codice per richiamarla l'ha implementato nel mainActivity per poi richiamare i bottoni del mydialog.xml. Ho provato ma Android Studio nel main Activity non riesce a vederli. Come posso bypassare questo problema?
La rignrazio in anticipo
Ciao simone,
il codice proposto nell'articolo è stato realizzato all'epoca con il plugin ADT di Android per l'IDE Eclipse.
Su due piedi non so se valgono le stesse regole per Android Studio, tra le app e sezioni di app realizzate fin'ora con Android Studio non mi sono mai posto il problema delle custom dialog, dovrei fare una prova, pertanto se hai maggiori info sul problema che ti si presenta fammele presenti e vediamo di risolvere.