Ecco i Dialog.
Mi pare di aver toccato in passato questo argomento, a proposito delle finestre di dialogo con le opzioni OK e Annulla e simili... ma non tanto da aver memorizzato qualcosa di utile.
Quello che può fare al caso mio è il DialogFragment, in modo da porgere all'utente l'informazione in modo obbligatorio, senza che magari una pressione involontaria di tasti possa far passare in secondo piano l'oggetto che presenta l'informazione.
Ci provo, poi a seconda dell'uso modificherò la cosa.
Questo è il tutorial di riferimento
Ho una classe che estende DialogFragment.
public class FireMissilesDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Ecco la classe che estende DialogFragment.
Ha un metodo onCreateDialog, che ha per parametro Bundle SavedInstanceState. Come per le activities.
E' di tipo Dialog, però, non void.
E vediamola...
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.dialog_fire_missiles)
Istanzia un oggetto builder di classe AlertDialog.Builder, mettendo come parametro getActivity().
Quindi usa il metodo setMessage con una stringa per parametro.
Quindi, in sintesi, istanzia AlertDialog.Builder con parametro getActivity() e usa il metodo setMessage di questo oggetto con una stringa per parametro.
Quindi abbiamo i metodi setPositiveButton e setNegativeButton che (ecco l'anomalia che ricordavo!) vanno scritti di seguito a .setMessage, e hanno come parametro una stringa e new DialogInterface.onClickListener.
public class FireMissilesDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.dialog_fire_missiles)
.setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// FIRE ZE MISSILES!
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}
Ma a questo punto forse si fa prima a scriverlo...
Creiamo dunque la classe che estende DialogFragment:
public class Dialogo extends DialogFragment{
}
Ora va overridata onCreateDialog
public class Dialogo extends DialogFragment{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
return null;
}
}
Ora si istanzia AlertDialog.Builder builder.
public class Dialogo extends DialogFragment{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
AlertDialog.Builder builder=new AlertDialog.Builder(getActivity());
return null;
}
}
(getActivity() è presentato come parametro di tipo Context. Forse andrà bene anche getApplicationContext()... sì, va bene, l'ho provato: non so se riferirsi al contesto dell'applicazione piuttosto che dell'activity possa creare qualche problema...)
Quindi si usa .setMessage con una stringa per parametro. Usando anche .setPositiveButton che oltre a una stringa richiede new DialogInterface.OnClickListener.
builder.setMessage("Ciao, Ciccio Bello!")
.setPositiveButton("Ciao", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Ecco, la cosa dovrebbe essere quasi completa.
Imposto anche il negative button:
builder.setMessage("Ciao, Ciccio Bello!")
.setPositiveButton("Ciao", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
return null;
Quindi si corregge return null con return builder.create:
public class Dialogo extends DialogFragment{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
AlertDialog.Builder builder=new AlertDialog.Builder(getApplicationContext());
builder.setMessage("Ciao, Ciccio Bello!")
.setPositiveButton("Ciao", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
return builder.create();
}
}
Ed eccola completa!
Ora rompo e ricostruisco come esercizio mnemonico...
Eccola ricostruita sbirciando un poco:
public class Dialogo extends DialogFragment{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
AlertDialog.Builder builder=new AlertDialog.Builder(getActivity());
builder.setMessage("Vuoi fare questa azione?")
.setPositiveButton("SI", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("SCELTA","POSITIVA");
}
})
.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("SCELTA", "NEGATIVA");
}
});
return builder.create();
}
}
Ora come la uso?
Il tutorial dice "create an instance of this class and call show". Proviamoci.
button=(Button)findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Dialogo mDialogo=new Dialogo();
mDialogo.show(getFragmentManager(),"boh");
}
});
Non ho ben capito cosa siano i due parametri di show, che ho compilato un po' a cavolo, ma di fatto la finestra compare!
E le scelte sono congruenti:
07-29 12:29:25.111: D/SCELTA(12881): NEGATIVA
07-29 12:29:33.569: D/SCELTA(12881): POSITIVA
07-29 12:29:56.431: D/SCELTA(12881): NEGATIVA
L'unica perplessità è che il tasto negativo viene a sinistra del positivo invece che a destra come mi aspettavo dall'ordine nel codice. Sarà così...
Ora, questa finestra di dialogo non viene eliminata se si clicca sull'activity in sottofondo, ma lo viene se si clicca sui tasti indietro, home e recents.
Praticamente non c'è differenza con un'activity a tutto schermo nella quale non si può cliccare su altra activity se non la stessa. Bisognerebbe trovare il modo di renderla veramente modale, ma adesso faccio la mia applicazione come avevo preventivato, senza cercare il modo di fare finestre modali, quindi si vedrà.