Visar materialdesigndialoger i en Android-app

Materialkonstruktionsgruppen hos Google definierar funktionaliteten i dialogrutor i Android enligt följande:

Dialogrutor informerar användarna om en viss uppgift och kan innehålla kritisk information, kräva beslut eller involvera flera uppgifter.

Nu har du förstått vilka dialoger som används, det är dags att lära sig att visa dem. I denna handledning tar jag dig genom processen att visa olika typer av materialdesigndialoger i Android. Vi täcker följande dialogrutor:

  • varna
  • singel och flera val 
  • tid och datumväljare
  • nedre arkdialogrutan
  • helskärmsdialogrutan

Ett provprojekt för denna handledning finns på vår GitHub repo för att du enkelt följer med.

1. Alert Dialog

Enligt den officiella Google-dokumentationen för materialdesign:

Varningar är brådskande avbrott, som kräver bekräftelse, som informerar användaren om en situation.

Skapa en Alert Dialog

Se till att du inkluderar den senaste appcompat artefakt i din build.gradle fil (appmodul). Den minsta tillåtna API-nivån är Android 4.0 (API-nivå 14). 

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

Nästa sak är att skapa en förekomst av AlertDialog.Builder

nya AlertDialog.Builder (this) .setTitle ("Nuke planet Jupiter?") .setMessage ("Observera att nuking planet Jupiter kommer att förstöra allt där inne.") .setPositiveButton ("Nuke", ny DialogInterface.OnClickListener () @Override public void onClick (DialogInterface dialog, int vilken) Log.d ("MainActivity", "Skicka atombomber till Jupiter");) .setNegativeButton ("Avbryt", ny DialogInterface.OnClickListener () @Override public void onClick (DialogInterface dialog, int som) Log.d ("MainActivity", "Aborting mission ...");) .show ();

Här skapade vi en förekomst av AlertDialog.Builder och började konfigurera förekomsten genom att ringa några setter metoder på den. Observera att vi använder AlertDialog från Android support artefakt.

importera android.support.v7.app.AlertDialog;

Här är detaljerna i setter metoderna som vi ringde på AlertDialog.Builder exempel. 

  • setTitle (): Ange texten som ska visas i dialogrutans titelfält. 
  • setMessage (): Ange meddelandet som ska visas i dialogrutan. 
  • setPositiveButton (): Det första argumentet som tillhandahålls är texten som ska visas i den positiva knappen medan det andra argumentet lyssnar på när den positiva knappen klickas. 
  • setNegativeButton (): det första argumentet som tillhandahålls är texten som ska visas i negativknappen medan det andra argumentet lyssnar upp när den negativa knappen klickas. 

Anteckna det AlertDialog.Builder har en setview () för att ställa in din anpassade layoutvy till den. 

För att visa vår dialog på skärmen, anropar vi bara show().

Det kallas en annan setter-metod setNeutralButton (). Om du anropar den här metoden lägger du till en annan knapp längst till vänster i dialogrutan. För att ringa denna metod måste vi vidarebefordra en Sträng som kommer att fungera som knapptext och även en lyssnare som kallas när knappen trycks in. 

ny AlertDialog.Builder (detta) // andra setter metoder .setNeutralButton ("Neutral", null) .show ()

Observera att vidrörning utanför dialogrutan automatiskt avvisar den. För att förhindra att det händer måste du ringa setCanceledOnTouchOutside ()AlertDialog instans och passera falsk som ett argument. 

AlertDialog dialog = ny AlertDialog.Builder (this) // efter att ha ringt setter metoder .create (); dialog.setCanceledOnTouchOutside (false); dialog.show ();

För att ytterligare förhindra att dialogrutan avvisas genom att trycka på TILLBAKA knappen måste du ringa setCancelable () på AlertDialog instans och passera falsk till det som ett argument. 

Styling a Alert Dialog

Det är ganska lätt att ställa in vår dialogruta. Vi skapar bara en anpassad stil i stilar.xml resurs. Observera att denna stilförälder är Theme.AppCompat.Light.Dialog.Alert. Med andra ord ärar denna stil vissa stilattribut från sin förälder. 

Vi börjar att anpassa dialogrutans stil genom att ange värdena för attributen som ska tillämpas på dialogrutan, till exempel kan vi ändra dialogrutans färg för att vara @android:Färg/ holo_orange_dark och ställ in dialogrutans bakgrund till en anpassad dragbar i vår dragbara resursmapp (android: windowBackground satt till @ Drawable / background_dialog).

Här är min background_dialog.xml resursfilen. 

        

Här skapade vi en anpassning InsetDrawable vilket tillåter oss att lägga till insatser på någon sida av ShapeDrawable. Vi skapade en rektangelform med hjälp av märka. Vi ställer in android: form attribut av  tagga till a rektangel (andra möjliga värden är linje, oval, ringa). Vi har en barnetikett som sätter radie av rektangelhörnen. För en solid fyllning lade vi till tagga med en android: färg attribut som anger vilken färg som ska användas. Slutligen gav vi våra dragbara gränser genom att använda tagga på .

För att tillämpa denna stil på dialogrutan, skickar vi bara den anpassade stilen till den andra parametern i AlertDialog.Builder konstruktör. 

AlertDialog dialog = ny AlertDialog.Builder (detta, R.style.CustomDialogTheme)

2. Bekräftelsesdialoger

Enligt materialdesigndokumentationen:

Bekräftelsesdialoger kräver att användarna uttryckligen bekräftar sitt val innan ett alternativ har åtagits. Användare kan till exempel lyssna på flera ringsignaler men bara göra ett slutligt val när de trycker på "OK".

Följande olika typer av bekräftelsedialogruta är tillgängliga:

  • flervalsdialogruta
  • singelval dialog
  • Datumväljare
  • tidväljaren

Multiple Choice Dialog 

Vi använder en multipel dialog om vi vill att användaren ska välja mer än ett objekt i en dialogruta. I en flervalsdialog visas en vallista för användaren att välja mellan. 

String [] multiChoiceItems = getResources (). GetStringArray (R.array.dialog_multi_choice_array); sista booleska [] checkedItems = false, false, false, false; nya AlertDialog.Builder (this) .setTitle ("Välj dina favoritfilmer") .setMultiChoiceItems (multiChoiceItems, checkedItems, new DialogInterface.OnMultiChoiceClickListener () @Override public void onClick (DialogInterface dialog, int index, boolean isChecked) Log.d ("MainActivity", "clicked item index är" + index);) .setPositiveButton ("Ok", null) .setNegativeButton ("Cancel", null) .show ();

För att skapa en dialog med flera valmöjligheter, ringer vi helt enkelt setMultiChoiceItems () setter metod på AlertDialog.Builder exempel. Inom denna metod passerar vi en Array av typ Sträng som den första parametern. Här är min array, som ligger i array-resursfilen /values/arrays.xml

   The Dark Knight Nyckeln till frihet Rädda menige Ryan När lammen tystnar  

Den andra parametern till metoden setMultiChoiceItems () accepterar en array som innehåller de objekt som är markerade. Värdet för varje element i checkedItems array motsvarar varje värde i multiChoiceItems array. Vi använde vårt checkedItems array (vars värden är alla falsk som standard) för att göra alla poster avmarkerade som standard. Med andra ord, det första föremålet "Dark Knight" är avmarkerad eftersom det första elementet i checkedItems array är falsk, och så vidare. Om det första elementet i checkedItems array var sant istället då "Dark Knight" skulle kontrolleras.

Observera att denna array checkedItems uppdateras när vi väljer eller klickar på något objekt som visas, till exempel om användaren ska välja "Nyckeln till frihet", kallelse checkedItems [1] skulle återvända Sann

Den sista parametern accepterar en instans av OnMultiChoiceClickListener. Här skapar vi helt enkelt en anonym klass och åsidosätter onClick (). Vi får en instans av den visade dialogrutan i den första parametern. I den andra parametern får vi indexet för det objekt som valts. Slutligen, i den sista parametern, får vi reda på om det valda objektet har kontrollerats eller inte. 

Single Choice Dialog 

I en valfri dialog, till skillnad från dialogrutan med flera val, kan endast ett objekt väljas. 

String [] singleChoiceItems = getResources (). GetStringArray (R.array.dialog_single_choice_array); int itemSelected = 0; nya AlertDialog.Builder (this) .setTitle ("Välj ditt kön") .setSingleChoiceItems (singleChoiceItems, itemSelected, new DialogInterface.OnClickListener () @Override public void onClick (DialogInterface dialoginterface, int selectedIndex) ) .setPositiveButton (" Ok ", null) .setNegativeButton (" Cancel ", null) .show ();

För att skapa en valfri dialog öppnar vi helt enkelt setSingleChoiceItems () setter på AlertDialog.Builder exempel. Inom denna metod passerar vi också en Array av typ Sträng som den första parametern. Här är den matris vi passerade, som ligger i arrays resursfilen: /values/arrays.xml

    Manlig Kvinna Övriga  

Den andra parametern för setSingleChoiceItems () används för att avgöra vilket objekt som är markerat. Den sista parametern i onClick () ger oss indexet för objektet som valts - till exempel, väljer du Kvinna objekt, värdet av selected kommer vara 1

Date Picker Dialog

Detta är en dialogväljare som används för att välja ett datum.

För att starta skapar vi en Kalender fältinstans i Huvudaktivitet och initiera den. 

public class MainActivity utökar AppCompatActivity Kalender mCalendar = Calendar.getInstance (); // ... 

Här ringde vi Calendar.getInstance () för att få aktuell tid (i standard tidzonen) och ställa in den till mCalendar fält. 

DatePickerDialog datePickerDialog = new DatePickerDialog (den här nya DatePickerDialog.OnDateSetListener () @Override public void onDateSet (DatePicker-visning, int år, int månadOfYear, int dayOfMonth) mCalendar.set (Kalender.YEAR, år); mCalendar.set .MONTH, monthOfYear); mCalendar.set (Kalender.DAY_OF_MONTH, dayOfMonth); String date = DateFormat.getDateInstance (DateFormat.MEDIUM) .format (calendar.getTime ()); Log.d ("MainActivity", "Vald datum är "+ datum);, mCalendar.get (Kalender.YEAR), mCalendar.get (Calendar.MONTH), mCalendar.get (Kalender.DAY_OF_MONTH)); datePickerDialog.show ();

För att visa en date picker dialog skapar vi en instans av DatePickerDialog. Här är förklaringen av parameterdefinitionerna när du skapar en förekomst av denna typ. 

  • Den första parametern accepterar ett överordnat sammanhang, till exempel i en Aktivitet, du använder detta, medan i a Fragment, du ringer getActivity ().  
  • Den andra parametern accepterar en lyssnare av typen OnDateSetListener. Den här lyssnaren onDateSet () kallas när användaren ställer in datumet. Inom den här metoden får vi det valda året, årets valda månad och den valda dagen i månaden. 
  • Den tredje parametern är det ursprungligen valda året. 
  • Den fjärde parametern är den initialt valda månaden (0-11). 
  • Den sista parametern är den inledningsvis valda dagen i månaden (1-31). 

Slutligen kallar vi show() metod för DatePickerDialog exempel för att visa den på den aktuella skärmen. 

Ställa in en anpassad tema

Det är ganska lätt att anpassa temat för datumväljardialogen (liknar vad vi gjorde till varningsdialogrutan). 

Kortfattat skapar du en anpassad dragbar, skapar en anpassad stil eller ett tema och tillämpar sedan det temat när du skapar en DatePickerDialog instans i den andra parametern.  

DatePickerDialog datePickerDialog = ny DatePickerDialog (detta, R.style.MyCustomDialogTheme, lyssnare, 2017, 26, 11);

Time Picker Dialog

Dialogen för tidsplockare låter användaren välja en tid och anpassar sig till användarens föredragna tidsinställning, det vill säga 12-timmars- eller 24-timmarsformatet.

Som du kan se i koden nedan skapar du en TimePickerDialog är ganska lik att skapa en DatePickerDialog. När du skapar en instans av TimePickerDialog, vi passerar i följande parametrar:

  • Den första parametern accepterar ett överordnat sammanhang. 
  • Den andra parametern accepterar en OnTimeSetListener exempel som fungerar som en lyssnare.
  • Den tredje parametern är dagens första timme. 
  • Den fjärde parametern är den första minuten.
  • Den sista parametern är att ställa in om vi vill ha vyn i 24-timmars- eller AM / PM-format. 
TimePickerDialog timePickerDialog = ny TimePickerDialog (den här nya TimePickerDialog.OnTimeSetListener () @Override public void onTimeSet (TimePicker timePicker, int timmeOfDay, int minut) mCalendar.set (Kalender.HOUR_OF_DAY, hourOfDay); mCalendar.set (Calendar.MINUTE, minut), Stringtid = DateFormat.getTimeInstance (DateFormat.SHORT) .format (calendar.getTime ()); Log.d ("MainActivity", "Selected time is" + time);, mCalendar.get (Kalender. HOUR_OF_DAY), calendar.get (Calendar.MINUTE), true); timePickerDialog.show ();

De onTimeSet () Metoden heter varje gång användaren har valt tiden. Inom denna metod får vi en förekomst av TimePicker, den valda timmen för den dag som valts, och även den valda minuten. 

För att visa denna dialog ringer vi fortfarande på show() metod.

Tidväljaren kan stylas på samma sätt som datumväljardialogen. 

3. Bottom Sheet Dialog

Enligt den officiella Google-dokumentationen för materialdesign:

Bottenarken glider upp från undersidan av skärmen för att avslöja mer innehåll.

För att börja använda dialogrutan nedersta ark måste du importera artefakt för designstöd, så besök din appmodul build.gradle fil för att importera den. 

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

Se till att aktiviteten eller fragmentet för dialogrutan med den nedersta arken dyker upp - dess förlagslayout är CoordinatorLayout

   

Här har vi också en FrameLayout det skulle fungera som en behållare för vårt bottenark. Observera det här FrameLayoutattribut är app: layout_behavior, vars värde är en speciell strängresurs som kartlägger android.support.design.widget.BottomSheetBehavior. Detta gör det möjligt för vår FrameLayout att visas som ett bottenark. Observera att om du inte inkluderar detta attribut kommer din app att krascha. 

public class MainActivity utökar AppCompatActivity // ... // ... privat BottomSheetDialog mBottomSheetDialog; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); // ... Visa bottomSheet = findViewById (R.id.framelayout_bottom_sheet); 

Här förklarade vi en förekomst av BottomSheetDialog som ett fält till vårt MainActivity.java och initialiserade den i onCreate () metod för vår verksamhet. 

Final View bottomSheetLayout = getLayoutInflater (). inflate (R.layout.bottom_sheet_dialog, null); (bottomSheetLayout.findViewById (R.id.button_close)) setOnClickListener (new View.OnClickListener () @Override public void onClick (Visa vy) mBottomSheetDialog.dismiss ();); (bottomSheetLayout.findViewById (R.id.button_ok)). setOnClickListener (New View.OnClickListener () @Override public void onClick (Visa v) Toast.makeText (getApplicationContext (), "Ok-knappen klickade", Toast.LENGTH_SHORT) .show();  ); mBottomSheetDialog = ny BottomSheetDialog (this); mBottomSheetDialog.setContentView (bottomSheetLayout); mBottomSheetDialog.show ();

I den föregående koden uppblåste vi vår bottenlayout R.layout.bottom_sheet_dialog. Vi satte lyssnare på Annullera och Ok knappar i bottom_sheet_dialog.xml. När Annullera knappen klickar vi enkelt avvisar dialogrutan. 

Vi initierade sedan vår mBottomSheetDialog fält och ställ in vyn med setContentView (). Slutligen kallar vi show() metod för att visa det på skärmen. 

Här är min bottom_sheet_dialog.xml:

     

Se till att du kolla Hur man använder bottenark med designstödsbiblioteket av Paul Trebilcox-Ruiz här på Envato Tuts + för att lära sig mer om bottenblad.

4. Fullskärmsdialog

Enligt den officiella Google-dokumentationen för materialdesign:

Dialogrutor med helskärm gruppera en rad uppgifter (till exempel skapa en kalenderpost) innan de kan begås eller kasseras. Inga val sparas tills "Spara" berörs. Genom att trycka på "X" kasseras alla ändringar och avslutas dialogrutan.

Låt oss nu se hur man skapar en helskärmsdialogruta. Först och främst, se till att du inkluderar Android support v4 artefakt i appens modul build.gradle. Detta krävs för att stödja Android 4.0 (API-nivå 14) och högre. 

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

Därefter kommer vi att skapa en FullscreenDialogFragment som utökar DialogFragment superklass. 

public class FullscreenDialogFragment utökar DialogFragment @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) Visa rootView = inflater.inflate (R.layout.full_screen_dialog, container, false); (rootView.findViewById (R.id.button_close)) setOnClickListener (ny View.OnClickListener () @Override public void onClick (Visa v) dismiss ();); returnera rootView;  @NonNull @Override public Dialog onCreateDialog (Bundle savedInstanceState) Dialogdialog = super.onCreateDialog (savedInstanceState); dialog.requestWindowFeature (Window.FEATURE_NO_TITLE); retur dialog; 

Här åsidosätter vi onCreateView () (precis som vi skulle göra med en vanlig Fragment). Inuti denna metod blåser vi bara upp och returnerar layouten (R.layout.full_screen_dialog) som ska fungera som den anpassade vyn för dialogrutan. Vi satte en OnClickListener på ImageButton (R.id.button_close) som kommer att avvisa dialogrutan när den klickas. 

Vi åsidosätter också onCreateDialog () och returnera ett Dialog. Inuti denna metod kan du också returnera en AlertDialog skapas med hjälp av en AlertDialog.Builder

Vår R.layout.full_screen_dialog består av en ImageButton, en Knapp, och lite Textview etiketter:

      

I ImageButton widgeten kommer du att se ett attribut app: srcCompat som refererar till en anpassad VectorDrawable (@ Drawable / ic_close). Denna anpassning VectorDrawable skapar X knappen, som stänger dialogrutan för helskärm när du trycker på. 

  

För att kunna använda detta app: srcCompat attribut, se till att du inkluderar den i din build.gradle fil. Konfigurera sedan din app för att använda vektorstödsbibliotek och lägg till vectorDrawables element till din build.gradle filen i appmodulen.

android defaultConfig vectorDrawables.useSupportLibrary = true

Vi gjorde det så att vi kan stödja alla Android-plattformsversioner tillbaka till Android 2.1 (API-nivå 7+). 

Slutligen, för att visa FullscreenDialogFragment, vi använder helt enkelt FragmentTransaction att lägga till vårt fragment till användargränssnittet. 

FragmentManager fragmentManager = getSupportFragmentManager (); FullscreenDialogFragment newFragment = nytt FullscreenDialogFragment (); FragmentTransaction transaktion = fragmentManager.beginTransaction (); transaction.setTransition (FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.add (android.R.id.content, newFragment) .addToBackStack (null) .commit ();

5. Överlevande Enhetsorientering

Observera att alla dialogrutor som diskuteras här, förutom dialogrutan för helskärm, avvisas automatiskt när användaren ändrar Android-enhetens skärmorientering - från stående till liggande (eller vice versa). Detta beror på att Android-systemet har förstört och återskapat Aktivitet så att den passar den nya orienteringen. 

För att vi ska behålla dialogrutan över skärmorienteringsändringar måste vi skapa en Fragment som utökar DialogFragment superklass (precis som vi gjorde för fullskärmsdialogen). 

Låt oss se ett enkelt exempel på en varningsdialog. 

public class AlertDialogFragment utökar DialogFragment implementerar DialogInterface.OnClickListener @Override public Dialog onCreateDialog (Bundle savedInstanceState) AlertDialog.Builder builder = nya AlertDialog.Builder (getActivity ()); setMessage ("Genom att aktivera supermakter, har du fler befogenheter att rädda världen.") .setPositiveButton ("Aktivera", detta) .setNegativeButton ("Cancel", detta ) .skapa());  @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 vilket) Toast.makeText (getActivity (), "vilket är" + vilket, Toast.LENGTH_LONG) .show (); 

Här skapade vi en klass som utökar DialogFragment och implementerar också DialogInterface.OnClickListener. Eftersom vi genomförde denna lyssnare måste vi åsidosätta onClick () metod. Observera att om vi trycker på den positiva eller negativa knappen, så här onClick () Metoden kommer att åberopas. 

Inuti vårt onCreateDialog (), vi skapar och returnerar en instans av AlertDialog

Vi har också överskridit:

  • onCancel (): Detta kallas om användaren trycker på TILLBAKA knappen för att lämna dialogrutan. 
  • onDismiss (): detta kallas när dialogrutan tvingas ut av någon anledning (TILLBAKA eller en knapp klicka). 

För att visa denna dialog ringer vi helt enkelt show() metod på en förekomst av vår AlertDialogFragment

nya AlertDialogFragment (). show (getSupportFragmentManager (), "alertdialog_sample");

Den första parametern är en förekomst av FragmentManager. Den andra parametern är en tagg som kan användas för att hämta detta fragment igen senare från FragmentManager via findFragmentByTag ().

Om du ändrar enhetens orientering från stående till liggande (eller vice versa), stängs inte alert-dialogrutan. 

Du kan följa liknande steg för de andra dialogtyperna för att behålla dialogrutan under enhetsrotation. Du skapar helt enkelt en Fragment som utökar DialogFragment superklass, och du skapar och returnerar den speciella dialogrutan i onCreateDialog ()

Progress Dialog (deprecated)

Vissa av er kanske har hört talas om ProgressDialog. Detta visar helt enkelt en dialog med en framstegsindikator på den. Jag har inte inkluderat det här, för ProgressDialog har avlägsnats i API-nivå 26, eftersom det kan leda till en dålig användarupplevelse för dina användare. Enligt den officiella dokumentationen:

ProgressDialog är en modal dialog som hindrar användaren från att interagera med appen. I stället för att använda den här klassen bör du använda en framdriftsindikator som ProgressBar, som kan läggas in i appens användargränssnitt. Alternativt kan du använda en anmälan för att informera användaren om uppgifternas framsteg.

Slutsats

I den här handledningen lärde du dig olika sätt att visa materialdesigndialoger i en Android-app. Vi omfattade följande materialdesigndialogtyper:

  • varningar
  • enkla och flera valdialoger
  • tid och datum plockare
  • nedre arkdialogrutan
  • helskärmsdialogrutan

Du lärde dig också hur du skapar en anpassad stil för en dialogruta och gör din dialog överlevande orienteringskonfigurationsändringar mellan landskap och porträtt med DialogFragment

Det rekommenderas starkt att du kolla in de officiella riktlinjerna för materialdesign för dialoger för att lära dig hur du utformar och använder dialogrutor korrekt i Android.   

För mer information om kodning för Android, kolla in några av våra andra kurser och handledning här på Envato Tuts+!