Il team di progettazione dei materiali di Google definisce la funzionalità dei dialoghi in Android come segue:
Le finestre di dialogo informano gli utenti su un'attività specifica e possono contenere informazioni critiche, richiedere decisioni o coinvolgere più attività.
Ora hai capito a cosa servono i dialoghi, ora è il momento di imparare a visualizzarli. In questo tutorial, ti illustrerò il processo di visualizzazione di diversi tipi di finestre di dialogo per la progettazione dei materiali in Android. Tratteremo le seguenti finestre di dialogo:
Un esempio di progetto per questo tutorial può essere trovato sul nostro repository GitHub per poter seguire facilmente.
Secondo la documentazione ufficiale di progettazione dei materiali di Google:
Gli avvisi sono interruzioni urgenti, che richiedono il riconoscimento, che informano l'utente di una situazione.
Assicurati di includere l'ultimo appcompat
artefatto nel tuo build.gradle
file (modulo app). Il livello di API minimo supportato è Android 4.0 (livello API 14).
dipendenze implementazione 'com.android.support:appcompat-v7:26.1.0'
La prossima cosa è creare un'istanza di AlertDialog.Builder
.
nuovo AlertDialog.Builder (this) .setTitle ("Nuke planet Jupiter?") .setMessage ("Notare che il pianeta Nuking Jupiter distruggerà tutto lì dentro.") .setPositiveButton ("Nuke", new DialogInterface.OnClickListener () @Override public void onClick (DialogInterface dialog, int which) Log.d ("MainActivity", "Invio di bombe atomiche a Jupiter");) .setNegativeButton ("Abort", new DialogInterface.OnClickListener () @ Override public void onClick (DialogInterface dialog, int which) Log.d ("MainActivity", "Aborting mission ...");) .show ();
Qui abbiamo creato un'istanza di AlertDialog.Builder
e ha iniziato a configurare l'istanza chiamando su di esso alcuni metodi di setter. Si noti che stiamo usando il AlertDialog
dall'artefatto di supporto Android.
import android.support.v7.app.AlertDialog;
Ecco i dettagli dei metodi di setter che abbiamo chiamato AlertDialog.Builder
esempio.
setTitle ()
: imposta il testo da mostrare nella barra del titolo della finestra di dialogo. setMessage ()
: imposta il messaggio da visualizzare nella finestra di dialogo. setPositiveButton ()
: il primo argomento fornito è il testo da mostrare nel pulsante positivo, mentre il secondo argomento è l'ascoltatore chiamato quando si fa clic sul pulsante positivo. setNegativeButton ()
: il primo argomento fornito è il testo da mostrare nel pulsante negativo, mentre il secondo argomento è il listener chiamato quando si fa clic sul pulsante negativo. Nota che AlertDialog.Builder
ha un ImpostaVisualizzazione ()
per impostare la visualizzazione del layout personalizzato su di esso.
Per mostrare la nostra finestra di dialogo sullo schermo, invochiamo mostrare()
.
C'è un altro metodo setter chiamato setNeutralButton ()
. Chiamando questo metodo si aggiungerà un altro pulsante sul lato sinistro della finestra di dialogo. Per chiamare questo metodo, dobbiamo passare a Stringa
che servirà come testo del pulsante e anche un ascoltatore che viene chiamato quando viene toccato il pulsante.
nuovo AlertDialog.Builder (this) // altri metodi setter .setNeutralButton ("Neutral", null) .show ()
Tieni presente che toccare fuori dalla finestra di dialogo lo ignorerà automaticamente. Per evitare che ciò accada, dovrai chiamare il setCanceledOnTouchOutside ()
sul AlertDialog
istanza e passaggio falso
come argomento.
AlertDialog dialog = new AlertDialog.Builder (this) // dopo aver chiamato i metodi setter .create (); dialog.setCanceledOnTouchOutside (false); Dialog.Show ();
Per impedire ulteriormente la chiusura della finestra di dialogo premendo il tasto INDIETRO pulsante, devi quindi chiamare setCancelable ()
sul AlertDialog
istanza e passaggio falso
ad esso come una discussione.
È abbastanza facile dare forma al nostro dialogo. Creiamo solo uno stile personalizzato nel stili.xml risorsa. Osserva che questo genitore di stile è Theme.AppCompat.Light.Dialog.Alert
. In altre parole, questo stile eredita alcuni attributi di stile dal suo genitore.
Iniziamo a personalizzare lo stile della finestra di dialogo impostando i valori degli attributi da applicare nella finestra di dialogo, ad esempio, possiamo cambiare il colore del pulsante di dialogo in modo che sia @android:
colore
/ holo_orange_dark
e anche impostare lo sfondo della finestra di dialogo su un drawable personalizzato nella nostra cartella delle risorse estraibili (Android: windowBackground
impostato @ Drawable / background_dialog
).
Ecco il mio background_dialog.xml file di risorse.
Qui abbiamo creato un'abitudine InsetDrawable
che ci consente di aggiungere inserimenti su qualsiasi lato del ShapeDrawable
. Abbiamo creato una forma rettangolare usando il
etichetta. Abbiamo impostato il android: Forma
attributo del
tag a rettangolo
(altri valori possibili sono linea
, ovale
, squillare
). Abbiamo un tag figlio
che imposta il raggio degli angoli del rettangolo. Per un solido riempimento, abbiamo aggiunto il
tag con un Android: il colore
attributo che indica quale colore usare. Infine, abbiamo dato il nostro confine disegnabile usando il
tag sul
.
Per applicare questo stile alla finestra di dialogo, passiamo semplicemente lo stile personalizzato al secondo parametro nel AlertDialog.Builder
costruttore.
AlertDialog dialog = new AlertDialog.Builder (this, R.style.CustomDialogTheme)
Secondo la documentazione di progettazione del materiale:
Le finestre di dialogo di conferma richiedono che gli utenti confermino esplicitamente la loro scelta prima che venga commessa un'opzione. Ad esempio, gli utenti possono ascoltare più suonerie, ma solo effettuare una selezione finale toccando "OK".
Sono disponibili i seguenti diversi tipi di finestre di conferma:
Utilizziamo una finestra di dialogo a scelta multipla quando vogliamo che l'utente selezioni più di un elemento in una finestra di dialogo. In una finestra di dialogo a scelta multipla, viene visualizzato un elenco di scelte da cui l'utente può scegliere.
String [] multiChoiceItems = getResources (). GetStringArray (R.array.dialog_multi_choice_array); final booleano [] checkedItems = false, false, false, false; nuovo AlertDialog.Builder (this) .setTitle ("Seleziona i tuoi film preferiti") .setMultiChoiceItems (multiChoiceItems, checkedItems, new DialogInterface.OnMultiChoiceClickListener () @Override public void onClick (DialogInterface dialog, int index, boolean isChecked) Log.d ("MainActivity", "indice oggetto selezionato" + indice);) .setPositiveButton ("Ok", null) .setNegativeButton ("Cancel", null) .show ();
Per creare una finestra di dialogo a scelta multipla, chiamiamo semplicemente il setMultiChoiceItems ()
metodo setter su AlertDialog.Builder
esempio. All'interno di questo metodo, passiamo a schieramento
di tipo Stringa
come il primo parametro. Ecco il mio array, che si trova nel file delle risorse degli array /values/arrays.xml.
- Il Cavaliere Oscuro
- La redenzione di Shawshank
- Salvate il soldato Ryan
- Il silenzio degli agnelli
Il secondo parametro del metodo setMultiChoiceItems ()
accetta un array che contiene gli elementi che sono controllati. Il valore di ogni elemento nel CheckedItems
matrice corrisponde a ciascun valore nel multiChoiceItems
array. Abbiamo usato il nostro CheckedItems
array (i cui valori sono tutti falso
per impostazione predefinita) per rendere deselezionati tutti gli elementi per impostazione predefinita. In altre parole, il primo elemento "Cavaliere Oscuro"
è deselezionato perché il primo elemento in CheckedItems
l'array è falso
, e così via. Se il primo elemento nel CheckedItems
array era vero invece, allora "Cavaliere Oscuro"
sarebbe controllato.
Si noti che questa matrice CheckedItems
viene aggiornato quando selezioniamo o facciamo clic su qualsiasi elemento visualizzato, ad esempio, se l'utente deve selezionare "The Shawshank Redemption"
, chiamata CheckedItems [1]
sarebbe tornato vero
.
L'ultimo parametro accetta un'istanza di OnMultiChoiceClickListener
. Qui semplicemente creiamo una classe anonima e sostituiamo al clic()
. Otteniamo un'istanza della finestra di dialogo mostrata nel primo parametro. Nel secondo parametro, otteniamo l'indice dell'articolo che è stato selezionato. Infine, nell'ultimo parametro, scopriamo se l'elemento selezionato è stato controllato o meno.
In una finestra di scelta singola, a differenza della finestra di dialogo a scelta multipla, è possibile selezionare solo un elemento.
String [] singleChoiceItems = getResources (). GetStringArray (R.array.dialog_single_choice_array); int itemSelected = 0; nuovo AlertDialog.Builder (this) .setTitle ("Seleziona il tuo sesso") .setSingleChoiceItems (singleChoiceItems, itemSelected, new DialogInterface.OnClickListener () @Override public void onClick (DialogInterface dialogInterface, int selectedIndex) ) .setPositiveButton (" Ok ", null) .setNegativeButton (" Cancel ", null) .show ();
Per creare una finestra di scelta singola, invochiamo semplicemente il setSingleChoiceItems ()
setter sul AlertDialog.Builder
esempio. All'interno di questo metodo, passiamo anche a schieramento
di tipo Stringa
come il primo parametro. Ecco la matrice che abbiamo passato, che si trova nel file delle risorse degli array: /values/arrays.xml.
- Maschio
- Femmina
- Altri
Il secondo parametro del setSingleChoiceItems ()
viene utilizzato per determinare quale elemento è selezionato. L'ultimo parametro in al clic()
ci dà l'indice dell'articolo che è stato selezionato, ad esempio, selezionando il Femmina articolo, il valore di selectedIndex
sarà 1
.
Questo è un selettore di dialoghi che viene utilizzato per selezionare una singola data.
Per iniziare, creeremo a Calendario
istanza di campo nel Attività principale
e inizializzalo.
public class MainActivity estende AppCompatActivity Calendar mCalendar = Calendar.getInstance (); // ...
Qui abbiamo chiamato Calendar.getInstance ()
per ottenere l'ora corrente (nel fuso orario predefinito) e impostarla su mCalendar
campo.
DatePickerDialog datePickerDialog = new DatePickerDialog (questo, new DatePickerDialog.OnDateSetListener () @Override public void onDateSet (DatePicker view, int anno, int monthOfYear, int dayOfMonth) mCalendar.set (Calendar.YEAR, year); mCalendar.set (Calendar .MONTH, monthOfYear); mCalendar.set (Calendar.DAY_OF_MONTH, dayOfMonth); String date = DateFormat.getDateInstance (DateFormat.MEDIUM) .format (calendar.getTime ()); Log.d ("MainActivity", "La data selezionata è "+ data);, mCalendar.get (Calendar.YEAR), mCalendar.get (Calendar.MONTH), mCalendar.get (Calendar.DAY_OF_MONTH)); datePickerDialog.show ();
Per mostrare una finestra di dialogo di selezione data, creiamo un'istanza di DatePickerDialog. Ecco la spiegazione delle definizioni dei parametri durante la creazione di un'istanza di questo tipo.
Attività
, usate Questo
, mentre in a Frammento
, chiami getActivity ()
. OnDateSetListener
. Questo ascoltatore onDateSet ()
viene chiamato quando l'utente imposta la data. All'interno di questo metodo, otteniamo l'anno selezionato, il mese selezionato dell'anno e anche il giorno selezionato del mese. 0
-11
). 1
-31
). Infine, chiamiamo il mostrare()
metodo del DatePickerDialog
istanza per visualizzarlo sullo schermo corrente.
È abbastanza facile personalizzare il tema della finestra di dialogo del selettore della data (simile a ciò che abbiamo fatto alla finestra di avviso).
In breve, crei un drawable personalizzato, crei uno stile o un tema personalizzato e quindi applichi quel tema durante la creazione di un tema DatePickerDialog
istanza nel secondo parametro.
DatePickerDialog datePickerDialog = new DatePickerDialog (this, R.style.MyCustomDialogTheme, listener, 2017, 26, 11);
La finestra di dialogo di selezione orari consente all'utente di selezionare un orario e di adattarsi all'impostazione preferita per l'orario dell'utente, ad esempio il formato di 12 ore o di 24 ore.
Come puoi vedere nel codice qui sotto, creando a TimePickerDialog
è abbastanza simile alla creazione di a DatePickerDialog
. Quando si crea un'istanza di TimePickerDialog
, passiamo nei seguenti parametri:
OnTimeSetListener
istanza che funge da ascoltatore.TimePickerDialog timePickerDialog = new TimePickerDialog (questo, new TimePickerDialog.OnTimeSetListener () @Override public void onTimeSet (TimePicker timePicker, int hourOfDay, int minute) mCalendar.set (Calendar.HOUR_OF_DAY, hourOfDay); mCalendar.set (Calendar.MINUTE, minuto); String time = DateFormat.getTimeInstance (DateFormat.SHORT) .format (calendar.getTime ()); Log.d ("MainActivity", "Ora selezionata" + ora);, mCalendar.get (Calendar. HOUR_OF_DAY), calendar.get (Calendar.MINUTE), true); timePickerDialog.show ();
Il onTimeSet ()
il metodo viene chiamato ogni volta che l'utente ha selezionato l'ora. All'interno di questo metodo, otteniamo un'istanza di TimePicker
, l'ora selezionata del giorno scelto e anche il minuto selezionato.
Per visualizzare questa finestra di dialogo, chiamiamo ancora il mostrare()
metodo.
Il Time Picker può essere abbinato in modo simile alla finestra di selezione del data.
Secondo la documentazione ufficiale di progettazione dei materiali di Google:
I fogli in basso scorrono verso l'alto dalla parte inferiore dello schermo per rivelare più contenuti.
Per iniziare a utilizzare la finestra di dialogo del foglio di sotto, devi importare l'artefatto del supporto alla progettazione, quindi visita i moduli dell'app build.gradle file per importarlo.
dipendenze implementazione 'com.android.support:appcompat-v7:26.1.0' implementazione 'com.android.support:design:26.1.0'
Assicurati che compaia l'attività o il frammento per la finestra di dialogo del basso, il suo layout genitore è il CoordinatorLayout
.
Qui abbiamo anche un FrameLayout
quello servirebbe da contenitore per il nostro foglio inferiore. Osserva quello di questo FrameLayout
Gli attributi di app: layout_behavior
, il cui valore è una risorsa stringa speciale associata a android.support.design.widget.BottomSheetBehavior
. Ciò consentirà il nostro FrameLayout
apparire come un foglio inferiore. Nota che se non includi questo attributo, la tua app si bloccherà.
public class MainActivity estende AppCompatActivity // ... // ... private BottomSheetDialog mBottomSheetDialog; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); // ... Visualizza bottomSheet = findViewById (R.id.framelayout_bottom_sheet);
Qui abbiamo dichiarato un'istanza di BottomSheetDialog
come un campo per il nostro MainActivity.java e inizializzato nel onCreate ()
metodo della nostra attività.
final Visualizza bottomSheetLayout = getLayoutInflater (). gonfia (R.layout.bottom_sheet_dialog, null); (bottomSheetLayout.findViewById (R.id.button_close)). setOnClickListener (new View.OnClickListener () @Override public void onClick (Visualizza vista) mBottomSheetDialog.dismiss ();); (bottomSheetLayout.findViewById (R.id.button_ok)). setOnClickListener (new View.OnClickListener () @Override public void onClick (View v) Toast.makeText (getApplicationContext (), "Pulsante OK fatto clic", Toast.LENGTH_SHORT) .mostrare(); ); mBottomSheetDialog = new BottomSheetDialog (this); mBottomSheetDialog.setContentView (bottomSheetLayout); mBottomSheetDialog.show ();
Nel codice precedente, abbiamo gonfiato il layout del foglio inferiore R.layout.bottom_sheet_dialog
. Impostiamo gli ascoltatori per il Annulla e Ok pulsanti nel bottom_sheet_dialog.xml. Quando il Annulla viene cliccato il pulsante, semplicemente ignoriamo la finestra di dialogo.
Abbiamo quindi inizializzato il nostro mBottomSheetDialog
campo e impostare la vista utilizzando setContentView ()
. Infine, chiamiamo il mostrare()
metodo per visualizzarlo sullo schermo.
Ecco il mio bottom_sheet_dialog.xml:
Assicurati di dare un'occhiata Come usare i fogli di fondo con la libreria di supporto del design di Paul Trebilcox-Ruiz qui su Envato Tuts + per saperne di più sui fogli di botttom.
Secondo la documentazione ufficiale di progettazione dei materiali di Google:
Le finestre di dialogo a schermo intero raggruppano una serie di attività (come la creazione di una voce del calendario) prima che possano essere impegnate o scartate. Nessuna selezione viene salvata fino a quando non viene toccato "Salva". Toccando la "X" scarta tutte le modifiche ed esce dalla finestra di dialogo.
Vediamo ora come creare una finestra di dialogo a schermo intero. Innanzitutto, assicurati di includere l'artefatto v4 per il supporto Android nel modulo della tua app build.gradle
. Questo è necessario per supportare Android 4.0 (livello API 14) e superiore.
implementazione 'com.android.support:support-v4:26.1.0'
Successivamente, creeremo un FullscreenDialogFragment
che estende il DialogFragment
super classe.
public class FullscreenDialogFragment estende DialogFragment @Override public Visualizza onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) Visualizza rootView = inflater.inflate (R.layout.full_screen_dialog, container, false); (rootView.findViewById (R.id.button_close)). setOnClickListener (new View.OnClickListener () @Override public void onClick (View v) dismiss ();); return rootView; @NonNull @Override public Dialog onCreateDialog (Bundle savedInstanceState) Dialog dialog = super.onCreateDialog (savedInstanceState); dialog.requestWindowFeature (Window.FEATURE_NO_TITLE); finestra di dialogo di ritorno;
Qui sostituiamo il onCreateView ()
(proprio come faremmo con un ordinario Frammento
). All'interno di questo metodo, semplicemente gonfiamo e restituiamo il layout (R.layout.full_screen_dialog
) che fungerà da visualizzazione personalizzata per il dialogo. Abbiamo impostato un OnClickListener
sul ImageButton
(R.id.button_close
) che chiuderà la finestra di dialogo quando si fa clic.
Abbiamo anche l'override onCreateDialog ()
e restituire un Dialogo
. All'interno di questo metodo, puoi anche restituire un AlertDialog
creati utilizzando un AlertDialog.Builder
.
Nostro R.layout.full_screen_dialog
consiste di un ImageButton
, un Pulsante
, e alcuni TextView
etichette:
Nel ImageButton
widget, vedrai un attributo app: srcCompat
che fa riferimento a un'abitudine VectorDrawable
(@ Drawable / ic_close
). Questa usanza VectorDrawable
crea il X pulsante, che chiude la finestra di dialogo a schermo intero quando viene toccato.
Per poter usare questo app: srcCompat
attributo, assicurati di includerlo nel tuo build.gradle file. Quindi, configura la tua app per utilizzare le librerie di supporto vettoriale e aggiungi il vectorDrawables
elemento al tuo build.gradle
file nel modulo dell'app.
android defaultConfig vectorDrawables.useSupportLibrary = true
Lo abbiamo fatto per poter supportare tutte le versioni della piattaforma Android su Android 2.1 (livello API 7+).
Infine, per mostrare il FullscreenDialogFragment
, noi semplicemente usiamo il FragmentTransaction
per aggiungere il nostro frammento all'interfaccia utente.
FragmentManager fragmentManager = getSupportFragmentManager (); FullscreenDialogFragment newFragment = new FullscreenDialogFragment (); FragmentTransaction transaction = fragmentManager.beginTransaction (); transaction.setTransition (FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.add (android.R.id.content, newFragment) .addToBackStack (null) .commit ();
Tieni presente che tutte le finestre di dialogo illustrate qui, ad eccezione della finestra di dialogo a schermo intero, verranno automaticamente ignorate quando l'utente cambia l'orientamento dello schermo del dispositivo Android, da verticale a orizzontale (o viceversa). Questo perché il sistema Android ha distrutto e ricreato il Attività
in modo da adattarsi al nuovo orientamento.
Per sostenere la finestra di dialogo attraverso le modifiche all'orientamento dello schermo, dovremo creare un Frammento
che estende il DialogFragment
super classe (proprio come abbiamo fatto per l'esempio di finestra di dialogo a schermo intero).
Vediamo un semplice esempio per una finestra di avviso.
public class AlertDialogFragment estende DialogFragment implementa DialogInterface.OnClickListener @Override public Dialog onCreateDialog (Bundle savedInstanceState) AlertDialog.Builder builder = new AlertDialog.Builder (getActivity ()); return (builder.setTitle ("Attiva i superpoteri?"). setMessage ("Attivando i superpoteri, avrai più poteri per salvare il mondo.") .setPositiveButton ("Attiva", questo) .setNegativeButton ("Annulla", questo ) .creare()); @Override public void onCancel (DialogInterface dialog) super.onCancel (dialog); @Override public void onDismiss (DialogInterface dialog) super.onDismiss (dialog); @Override public void onClick (DialogInterface dialog, int which) Toast.makeText (getActivity (), "which is" + which, Toast.LENGTH_LONG) .show ();
Qui, abbiamo creato una classe che estende il DialogFragment
e implementa anche il DialogInterface.OnClickListener
. Poiché abbiamo implementato questo listener, dobbiamo ignorare il al clic()
metodo. Nota che se tocchiamo il pulsante positivo o negativo, questo al clic()
il metodo sarà invocato.
Dentro il nostro onCreateDialog ()
, creiamo e restituiamo un'istanza di AlertDialog
.
Abbiamo anche scavalcato:
onCancel ()
: questo è chiamato se l'utente preme il tasto INDIETRO pulsante per uscire dalla finestra di dialogo. onDismiss ()
: questo viene chiamato ogni volta che la finestra di dialogo viene forzata per qualsiasi motivo (INDIETRO o un clic del tasto). Per mostrare questo dialogo, chiamiamo semplicemente il mostrare()
metodo su un'istanza del nostro AlertDialogFragment
.
nuovo AlertDialogFragment (). show (getSupportFragmentManager (), "alertdialog_sample");
Il primo parametro è un'istanza di FragmentManager
. Il secondo parametro è un tag che può essere utilizzato per recuperare questo frammento di nuovo in seguito dal FragmentManager
attraverso findFragmentByTag ()
.