Se afișează dialogurile de design material într-o aplicație Android

Echipa de design material de la Google definește funcționalitatea dialogurilor din Android după cum urmează:

Dialogurile informează utilizatorii despre o anumită sarcină și pot conține informații critice, necesită decizii sau implică mai multe sarcini.

Acum ați înțeles ce dialoguri sunt folosite, acum este timpul să învățați cum să le afișați. În acest tutorial, vă voi face prin procesul de a afișa diferite tipuri de dialoguri de design material în Android. Vom acoperi următoarele dialoguri:

  • alerta
  • singură și la alegere multiplă 
  • selector de timp și dată
  • dialogul din partea de jos a colii
  • ecran pe ecran complet

Un exemplu de proiect pentru acest tutorial poate fi găsit pe replica noastră GitHub pentru a vă putea urmări cu ușurință.

1. Dialogul de avertizare

Potrivit documentației oficiale de proiectare material Google:

Alertele sunt întreruperi urgente, necesitând recunoaștere, care informează utilizatorul despre o situație.

Crearea unui dialog de alertă

Asigurați-vă că includeți cele mai recente appcompat artefact în dvs. build.gradle fișier (modul de aplicație). Nivelul minim API acceptat este Android 4.0 (nivel 14 API). 

dependencies implementation 'com.android.support:appcompat-v7:26.1.0'

Următorul lucru este să creați un exemplu de AlertDialog.Builder

AlertDialog.Builder (acest) .setTitle ("Nuke planet Jupiter?") .setMessage ("Rețineți că planeta de nuci Jupiter va distruge totul acolo" public void onClick (dialog DialogInterface, int care) Log.d ("MainActivity", "Trimiterea bombelor atomice la Jupiter");) .setNegativeButton ("Abort", new DialogInterface.OnClickListener (Dialog DialogInterface, int care) Log.d ("MainActivity", "Aborting mission ...");) .show ();

Aici am creat o instanță de AlertDialog.Builder și a început configurarea instanței apelând la unele metode de setter pe ea. Rețineți că folosim AlertDialog de la artefactul de asistență Android.

import șiroid.support.v7.app.AlertDialog;

Iată detaliile metodelor de setare pe care le-am chemat AlertDialog.Builder instanță. 

  • SetTitle (): setați textul pe care doriți să îl afișați în bara de titlu a dialogului. 
  • setMessage (): setați mesajul care să fie afișat în dialog. 
  • setPositiveButton (): primul argument furnizat este textul care se afișează în butonul pozitiv, în timp ce al doilea argument este ascultătorul apelat atunci când este apăsat butonul pozitiv. 
  • setNegativeButton (): primul argument furnizat este textul care se afișează în butonul negativ, în timp ce al doilea argument este ascultătorul apelat atunci când este apăsat butonul negativ. 

Rețineți că AlertDialog.Builder are o setview () pentru a seta vizualizarea personalizată a aspectului. 

Pentru a afișa dialogul nostru pe ecran, noi invocăm spectacol().

Există o altă metodă de setare numită setNeutralButton (). Apelarea acestei metode va adăuga un alt buton în partea stângă a ferestrei de dialog. Pentru a apela această metodă, trebuie să trecem a Şir care va servi drept text de buton, precum și un ascultător care se numește atunci când este apăsat butonul. 

new AlertDialog.Builder (this) // alte metode de setare .setNeutralButton ("Neutral", null) .show ()

Rețineți că atingerea în afara dialogului o va respinge automat. Pentru a preveni acest lucru, va trebui să apelați setCanceledOnTouchOutside () pe AlertDialog instanță și trecere fals ca argument. 

AlertDialog dialog = new AlertDialog.Builder (this) // după apelarea metodei setter .create (); dialog.setCanceledOnTouchOutside (false); dialog.show ();

Pentru a preveni înlăturarea dialogului apăsând tasta ÎNAPOI buton, trebuie să sunați setCancelable () pe AlertDialog instanță și trecere fals ca argument. 

Modelarea unui dialog de alertă

Este destul de ușor să ne dialogăm dialogul. Doar creăm un stil personalizat în stiluri.xml resursă. Observați că acest parinte stil este Theme.AppCompat.Light.Dialog.Alert. Cu alte cuvinte, acest stil moștenește anumite atribute de stil de la părintele său. 

Începem personalizarea stilului de dialog prin setarea valorilor atributelor care urmează să fie aplicate în dialog - de exemplu, putem schimba culoarea butonului de dialog pentru a fi @android:culoare/ holo_orange_dark și, de asemenea, setați fundalul de dialog într-un desen personalizat în folderul de resurse remorci (Android: windowBackground setat la @ Drawable / background_dialog).

Aici e al meu background_dialog.xml fișier de resurse. 

        

Aici am creat un obicei InsetDrawable care ne permite să adăugăm inserții pe orice parte a paginii ShapeDrawable. Am creat o formă de dreptunghi folosind etichetă. Am setat Android: forma atributul  eticheta la a dreptunghi (alte valori posibile sunt linia, oval, inel). Avem o etichetă pentru copii care stabilește raza colțurilor dreptunghiului. Pentru o umplutură solidă, am adăugat eticheta cu un Android: culoare atribut care indică ce culoare să utilizați. În cele din urmă, am dat o margine de tractare prin folosirea etichetă pe .

Pentru a aplica acest stil dialogului, trecem doar stilul personalizat la al doilea parametru din AlertDialog.Builder constructor. 

AlertDialog dialog = nou AlertDialog.Builder (aceasta, R.style.CustomDialogTheme)

2. Dialoguri de confirmare

În conformitate cu documentația de proiectare materială:

Dialogurile de confirmare solicită utilizatorilor să confirme în mod explicit alegerea lor înainte de a se angaja o opțiune. De exemplu, utilizatorii pot asculta mai multe tonuri de apel, dar pot face o selecție finală numai când ating "OK".

Sunt disponibile următoarele tipuri diferite de dialog de confirmare:

  • dialog de mai multe opțiuni
  • dialog de o singură alegere
  • selector de date
  • selector de timp

Dialogul cu mai multe opțiuni 

Utilizăm un dialog cu mai multe opțiuni atunci când dorim ca utilizatorul să selecteze mai mult de un element într-un dialog. Într-un dialog cu mai multe opțiuni, este afișată o listă de opțiuni pentru care utilizatorul poate alege. 

String [] multiChoiceItems = getResources (). GetStringArray (R.array.dialog_multi_choice_array); finale boolean [] checkedItems = false, false, false, false; noul AlertDialog.Builder (this) .setTitle ("Selectați filmele preferate") .setMultiChoiceItems (multiChoiceItems, checkedItems, noul DialogInterface.OnMultiChoiceClickListener) Log.d public void onClick (dialog DialogInterface, index int, boolean isChecked) ("MainActivity", "indicele elementului clicat este" + index);) .setPositiveButton ("Ok", null) .setNegativeButton ("Cancel".

Pentru a crea un dialog cu mai multe opțiuni, sunăm pur și simplu setMultiChoiceItems () setter metoda pe AlertDialog.Builder instanță. În cadrul acestei metode, trecem printr-o metodă mulțime de tip Şir ca primul parametru. Iată matricea mea, localizată în fișierul de resurse al matricei /values/arrays.xml

   Cavalerul intunecat Răscumpărarea Shawshank Salvați soldatul Ryan Tacerea mieilor  

Al doilea parametru al metodei setMultiChoiceItems () acceptă o matrice care conține elementele care sunt bifate. Valoarea fiecărui element din checkedItems matrice corespunde fiecărei valori din multiChoiceItems matrice. Ne-am folosit checkedItems array (ale căror valori sunt toate fals în mod implicit) pentru a face ca toate elementele să nu fie bifate în mod prestabilit. Cu alte cuvinte, primul element "Cavalerul intunecat" este debifată deoarece primul element din checkedItems array este fals, si asa mai departe. Dacă primul element din checkedItems array a fost adevărat în schimb, atunci "Cavalerul intunecat" ar fi verificat.

Rețineți că această matrice checkedItems este actualizată când selectăm sau dăm clic pe orice element afișat - de exemplu, dacă utilizatorul ar trebui să selecteze "Răscumpărarea lui Shawshank", apel checkedItems [1] s-ar întoarce Adevărat

Ultimul parametru acceptă o instanță de OnMultiChoiceClickListener. Aici creăm pur și simplu o clasă anonimă și o suprascrie onClick (). Obținem o instanță a dialogului afișat în primul parametru. În al doilea parametru, obținem indexul elementului care a fost selectat. În final, în ultimul parametru, aflăm dacă elementul selectat a fost bifat sau nu. 

Dialogul cu o singură alegere 

Într-un dialog de alegere unică, spre deosebire de dialogul cu mai multe opțiuni, poate fi selectat un singur element. 

Șirul [] singleChoiceItems = getResources (). GetStringArray (R.array.dialog_single_choice_array); int itemSelected = 0; noul AlertDialog.Builder (this) .setTitle ("Selectați sexul") .setSingleChoiceItems (singleChoiceItems, itemSelected, new DialogInterface.OnClickListener) @Override public void onClick (DialogInterface dialogInterface, int selectedIndex) ) .setPositiveButton Ok ", null) .setNegativeButton (" Anulare ", null) .show ();

Pentru a crea un dialog de alegere unică, pur și simplu invocăm setSingleChoiceItems () setter pe de AlertDialog.Builder instanță. În cadrul acestei metode, trecem și noi mulțime de tip Şir ca primul parametru. Iată matricea pe care am trecut-o, care este localizată în fișierul de resurse al arhivelor: /values/arrays.xml

    Masculin Femeie Alții  

Al doilea parametru al setSingleChoiceItems () este utilizat pentru a determina care element este verificat. Ultimul parametru din onClick () ne dă indexul elementului selectat - de exemplu, selectând Femeie element, valoarea lui selectedIndex va fi 1

Dialogul de selectare a datei

Acesta este un selector de dialog care este folosit pentru a selecta o singură dată.

Pentru a începe, vom crea o Calendar instanță în domeniu Activitate principala și inițializați-o. 

clasa publica MainActivity extinde AppCompatActivity Calendar mCalendar = Calendar.getInstance (); // ... 

Aici am sunat Calendar.getInstance () pentru a obține ora curentă (în fusul orar implicit) și pentru ao seta la mCalendar camp. 

DatePickerDialog datePickerDialog = new DatePickerDialog (acest nou, DatePickerDialog.OnDateSetListener () @Override public void onDateSet (vizualizare DatePicker, int year, int monthOfYear, int dayOfMonth) mCalendar.set (Calendar.YEAR, year); .Month, monthOf Year), mCalendar.set (Calendar.DAY_OF_MONTH, dayOfMonth), String date = DateFormat.getDateInstance (DateFormat.MEDIUM) .format (calendar.getTime ()); Log.d ("MainActivity" "+ data);, mCalendar.get (Calendar.YEAR), mCalendar.get (Calendar.MONTH), mCalendar.get (Calendar.DAY_OF_MONTH)); datePickerDialog.show ();

Pentru a afișa un dialog de selectare a datei, vom crea o instanță a DatePickerDialog. Iată explicația definițiilor parametrilor atunci când creați o instanță de acest tip. 

  • Primul parametru acceptă un context părinte - de exemplu, într-un Activitate, să utilizați acest, în timp ce în a Fragment, sunați getActivity ().  
  • Al doilea parametru acceptă un ascultător de tip OnDateSetListener. Acest ascultător onDateSet () se numește când utilizatorul stabilește data. În cadrul acestei metode, obținem anul selectat, luna selectată a anului și, de asemenea, ziua selectată a lunii. 
  • Al treilea parametru este anul selectat inițial. 
  • Al patrulea parametru este luna selectată inițial (0-11). 
  • Ultimul parametru este ziua selectată inițial a lunii (1-31). 

În cele din urmă, numim spectacol() metodă a DatePickerDialog exemplu pentru a fi afișat pe ecranul curent. 

Setarea unei teme personalizate

Este destul de ușor să personalizați tema dialogului de selectare a datei (similar cu ceea ce am făcut în dialogul de alertă). 

Pe scurt, creați un trasabil personalizat, creați un stil personalizat sau o temă și apoi aplicați acea temă atunci când creați un DatePickerDialog exemplu în al doilea parametru.  

DataPickerDialog datePickerDialog = new DatePickerDialog (aceasta, R.style.MyCustomDialogTheme, ascultător, 2017, 26, 11);

Dialogul de selectare a timpului

Dialogul de selectare a timpului permite utilizatorului să aleagă un timp și ajustează setarea de timp preferată a utilizatorului, adică formatul de 12 ore sau 24 de ore.

După cum puteți vedea în codul de mai jos, crearea unui TimePickerDialog este destul de similar cu crearea unui DatePickerDialog. Când creați o instanță a TimePickerDialog, trecem în următorii parametri:

  • Primul parametru acceptă un context părinte. 
  • Al doilea parametru acceptă o OnTimeSetListener instanță care servește drept ascultător.
  • Al treilea parametru este ora inițială a zilei. 
  • Al patrulea parametru este minutul inițial.
  • Ultimul parametru este de a stabili dacă dorim vizualizarea în format 24 de ore sau AM / PM. 
TimpPickerDialog timePickerDialog = new TimePickerDialog (acest nou TimePickerDialog.OnTimeSetListener () @Override public void onTimeSet (TimePicker timePicker, int hourOfDay, int minute) mCalendar.set (Calendar.HOUR_OF_DAY, hourOfDay); mCalendar.set (Calendar.MINUTE, minute); Timp șir = DateFormat.getTimeInstance (DateFormat.SHORT) .format (calendar.getTime ()); Log.d ("MainActivity", "Timpul selectat este" +)), mCalendar.get (Calendar. HOUR_OF_DAY), calendar.get (Calendar.MINUTE), adevărat); timePickerDialog.show ();

onTimeSet () metoda se numește de fiecare dată când utilizatorul a selectat timpul. În cadrul acestei metode, primim o instanță a TimePicker, ora selectată a zilei alese și, de asemenea, minutul selectat. 

Pentru a afișa acest dialog, sunăm încă spectacol() metodă.

Selectorul de timp poate fi decorat în mod similar cu dialogul de selectare a datei. 

3. Dialogul din partea inferioară a foii

Potrivit documentației oficiale de proiectare material Google:

Foi inferioare se aliniază din partea de jos a ecranului pentru a descoperi mai mult conținut.

Pentru a începe să utilizați dialogul din foaia inferioară, trebuie să importați artefactul de proiectare - vizitați modulul de aplicații build.gradle fișier pentru a le importa. 

dependencies implementation 'com.android.support:appcompat-v7:26.1.0' implementare 'com.android.support:design:26.1.0'

Asigurați-vă că se va afișa activitatea sau fragmentul pentru dialogul foaie inferioară - aspectul părintelui este CoordinatorLayout

   

Aici avem și o FrameLayout care ar servi ca un container pentru foaia de jos. Observați unul dintre acestea FrameLayoutare atribute app: layout_behavior, a căror valoare este o resursă de șir specială care să corespundă hărților android.support.design.widget.BottomSheetBehavior. Acest lucru ne va permite FrameLayout să apară ca o foaie inferioară. Rețineți că dacă nu includeți acest atribut, aplicația dvs. se va prăbuși. 

clasa publica MainActivity extinde AppCompatActivity // ... // ... privat BottomSheetDialog mBottomSheetDialog; @Override protejate void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); // ... Vezi bottomSheet = findViewById (R.id.framelayout_bottom_sheet); 

Aici am declarat un exemplu BottomSheetDialog ca un domeniu pentru noi MainActivity.java și a inițializat-o în onCreate () metodă a activității noastre. 

finală Vizualizare bottomSheetLayout = getLayoutInflater () inflate (R.layout.bottom_sheet_dialog, null); (bottomSheetLayout.findViewById (R.id.button_close)) setOnClickListener (noul View.OnClickListener () @Override public void onClick (Vizualizare vizualizare) mBottomSheetDialog.dismiss ();); (bottomApplicationContext (), "Buton Ok clicked", Toast.LENGTH_SHORT) (setareNumber.findViewById (R.id.button_ok)) setOnClickListener (new View.OnClickListener () @Override public void onClick .spectacol();  ); mBottomSheetDialog = nou BottomSheetDialog (acest); mBottomSheetDialog.setContentView (bottomSheetLayout); mBottomSheetDialog.show ();

În codul precedent, ne-a umflat aspectul foaie de jos R.layout.bottom_sheet_dialog. Am stabilit ascultători pentru Anulare și O.K butoane din bottom_sheet_dialog.xml. Cand Anulare butonul este apăsat, pur și simplu renunțăm la dialog. 

Apoi am inițializat-o pe noi mBottomSheetDialog câmp și setați vizualizarea folosind setContentView (). În cele din urmă, numim spectacol() metodă de afișare pe ecran. 

Aici e al meu bottom_sheet_dialog.xml:

     

Asigurați-vă că verificați modul de utilizare a foilor inferioare cu Biblioteca de suport de proiectare de către Paul Trebilcox-Ruiz aici pe Envato Tuts + pentru a afla mai multe despre foile de îmbinare.

4. Dialog pe ecran complet

Potrivit documentației oficiale de proiectare material Google:

Afișările pe ecran pe ecran grupează o serie de sarcini (cum ar fi crearea unei intrări în agendă) înainte ca acestea să poată fi angajate sau eliminate. Nu sunt salvate selecții până când nu este atins "Salvare". Atingerea "X" elimină toate modificările și iese din dialog.

Să vedem acum cum să creăm un dialog pe ecran complet. Mai întâi, asigurați-vă că includeți artefactul v4 pentru suport Android în modulul aplicației build.gradle. Acest lucru este necesar pentru a suporta Android 4.0 (API nivel 14) și mai sus. 

implementare 'com.android.support:support-v4:26.1.0'

Apoi, vom crea o FullscreenDialogFragment care extinde DialogFragment clasa super. 

clasa publica FullscreenDialogFragment extinde DialogFragment @Overide public View onCreateView (LayoutInflater inflater, Container ViewGroup, Bundle savedInstanceState) View rootView = inflater.inflate (R.layout.full_screen_dialog, container, false); (rootView.findViewById (R.id.button_close)) setOnClickListener (noul View.OnClickListener () @Override public void onClick (Vizualizare v) dismiss ();); returnează rootView;  @NonNull @Override Dialogul public onCreateDialog (Bundle savedInstanceState) Dialogul dialogului = super.onCreateDialog (savedInstanceState); dialog.requestWindowFeature (Window.FEATURE_NO_TITLE); dialog de întoarcere; 

Aici ne suprascriem onCreateView () (la fel cum am face și cu un obișnuit Fragment). În această metodă, pur și simplu inflamați și readuceți aspectul (R.layout.full_screen_dialog) care va servi drept vizualizare personalizată pentru dialog. Am stabilit un OnClickListener pe ImageButton (R.id.button_close) care va respinge dialogul când este făcut clic. 

De asemenea, suprascrie onCreateDialog () și să se întoarcă un dialog. În cadrul acestei metode, puteți să-l returnați AlertDialog creat folosind un AlertDialog.Builder

Al nostru R.layout.full_screen_dialog este alcătuită dintr - un ImageButton, A Buton, si ceva TextView etichete:

      

În ImageButton widget, veți vedea un atribut app: srcCompat care se referă la un obicei VectorDrawable (@ Drawable / ic_close). Acest obicei VectorDrawable creează X buton, care închide dialogul de ecran complet când este apăsat. 

  

Pentru a utiliza acest lucru app: srcCompat atributul, asigurați-vă că îl includeți în dvs. build.gradle fişier. Apoi, configurați aplicația pentru a utiliza bibliotecile de suport vectorial și adăugați-o vectorDrawables element pentru dvs. build.gradle fișier în modulul aplicației.

android defaultConfig vectorDrawables.useSupportLibrary = true

Am făcut acest lucru astfel încât să putem sprijini toate versiunile de platforme Android înapoi la Android 2.1 (API nivel 7+). 

În cele din urmă, pentru a arăta FullscreenDialogFragment, pur și simplu folosim FragmentTransaction pentru a adăuga fragmentul nostru la interfața utilizator. 

FragmentManager fragmentManager = getSupportFragmentManager (); FullscreenDialogFragment newFragment = noul ecran FullscreenDialogFragment (); FragmentTransaction transaction = fragmentManager.beginTransaction (); transaction.setTransition (FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.add (șiroid.R.id.content, newFragment) .addToBackStack (null) .commit ();

5. Orientarea dispozitivului supraviețuitor

Rețineți că toate dialogurile discutate aici, cu excepția dialogului pe ecran complet, vor fi respinse automat atunci când utilizatorul modifică orientarea pe ecran a dispozitivului Android - de la portret la peisaj (sau invers). Acest lucru se datorează faptului că sistemul Android a distrus și recreat Activitate astfel încât să se potrivească noii orientări. 

Pentru ca noi să susținem dialogul în funcție de modificările orientării ecranului, va trebui să creăm un Fragment care extinde DialogFragment clasa super (așa cum am făcut pentru exemplul de dialog de pe ecran complet). 

Să vedem un exemplu simplu pentru un dialog de alertă. 

public class AlertDialogFragment extinde DialogFragment implementează DialogInterface.OnClickListener @Override public Dialog onCreateDialog (Bundle savedInstanceState) AlertDialog.Builder builder = nou AlertDialog.Builder (getActivity ()); ("Activând superputeri, veți avea mai multe puteri pentru a salva lumea") .setPositiveButton ("Activare", acest lucru) .setNegativeButton ("Anulare", acest lucru ) .crea());  @Override public void onCancel (dialog DialogInterface) super.onCancel (dialog);  @Override public void peDismiss (DialogInterface dialog) super.onDismiss (dialog);  @Override public void onClick (dialog DialogInterface, int care) Toast.makeText (getActivity (), "+, care, Toast.LENGTH_LONG) .show (); 

Aici, am creat o clasă care extinde DialogFragment și, de asemenea, pune în aplicare DialogInterface.OnClickListener. Pentru că am implementat acest ascultător, trebuie să ignorăm onClick () metodă. Rețineți că dacă atingem butonul pozitiv sau negativ, acest lucru onClick () metoda va fi invocată. 

În interiorul nostru onCreateDialog (), creăm și returnează o instanță de AlertDialog

De asemenea, am mai rămas:

  • onCancel (): aceasta se numește dacă utilizatorul apasă ÎNAPOI pentru a ieși din dialog. 
  • onDismiss (): aceasta se numește ori de câte ori dialogul este forțat din orice motiv (ÎNAPOI sau un clic pe buton). 

Pentru a afișa acest dialog, sunăm pur și simplu spectacol() metoda pe un exemplu al nostru AlertDialogFragment

noul AlertDialogFragment () arată (getSupportFragmentManager (), "alertdialog_sample");

Primul parametru este o instanță a FragmentManager. Al doilea parametru este o etichetă care poate fi utilizată pentru a prelua din nou acest fragment din nou FragmentManager prin intermediul findFragmentByTag ().

Acum, dacă schimbați orientarea dispozitivului de la portret la peisaj (sau invers), dialogul de alertă nu va fi respins. 

Puteți urma pași asemănători pentru celelalte tipuri de dialog pentru a menține dialogul în timpul rotirii dispozitivului. Pur și simplu creați un Fragment care extinde DialogFragment clasa super, și creați și returnați dialogul special în onCreateDialog ()

Dialogul de progres (depreciat)

Unii dintre voi ați auzit despre ProgressDialog. Acest lucru arată pur și simplu un dialog cu un indicator de progres pe el. Nu l-am inclus aici, pentru că ProgressDialog a fost depreciat în nivelul 26 al API - deoarece poate duce la o experiență de utilizator rău pentru utilizatorii dvs. Conform documentației oficiale:

ProgressDialog este un dialog modal, care împiedică utilizatorul să interacționeze cu aplicația. În loc să utilizați această clasă, ar trebui să utilizați un indicator de progres cum ar fi Bara de progres, care pot fi încorporate în interfața UI a aplicației. Alternativ, puteți utiliza o notificare pentru a informa utilizatorul despre progresul activității.

Concluzie

În acest tutorial, aț

Cod