Leniwce.com | blog technologiczny
Nie taki dialog straszny, czyli kilka słów o okienkach dialogowych
Bartosz Lewandowski, 2011-07-30 00:25:02
kategoria: Android, Java

Nie wiem dlaczego, ale budowanie okienek dialogowych w Androdzie początkowo działało mi na nerwy. Odnosiłem wrażenie, że kod jest mało czytelny, opcje są zbyt rozbudowane. Jednak po czasie się przyzwyczaiłem i mogę stwierdzić, że implementacja jest całkiem przyjemna. Postanowiłem więc podzielić się metodą budowy okienek dialogowych, przy wykorzystaniu klasy AlertDialog, na trzech przykładach.

Jak zwykle bywa, na początek przykład najprostszy. Zaczynam więc podstawowym dialogiem, pozwalającym na potwierdzenie chęci wykonania czynności. Czyli taki dialog "tak/nie", zilustrowany na grafice poniżej:

 

Budowa jest prosta. Tworzymy obiekt AlertBuilder, określamy poprzez metody tytuł, treść. Definiujemy dwa przyciski (positiveButton oraz negativeButton).
Dla każdego z buttonów dodajemy listenera na zdarzenie onClick (w przykładzie dodam tylko dla jednego przycisku, drugi nie generuje akcji, wprowadzę więc null). 

new AlertDialog.Builder(this)
.setTitle("Potwierdź")
.setMessage("Usunąć dokument")
.setPositiveButton("tak", new DialogInterface.OnClickListener() 
{
  @Override
  public void onClick(DialogInterface dialog, int which) 
  {
    Toast.makeText(Dialogs.this, "Wybrano tak", Toast.LENGTH_LONG).show();
   }
})
.setNegativeButton("nie", null)
.show();

Jak widać w zamieszczonym kodzie, po naciśnięciu przycisku tak pojawi się komunikat informujący o zdarzeniu (generowany poprzez Toast).

W drugim przykładzie wprowadzę drobne ale istotne zmiany. Wypada przechowywać komunikaty w pliku strings.xml, a nie jawnie w kodzie. AlertDialog w metodach (setTile, setMessage, etc.) pozwala również na wprowadzania identyfikatorów komunikatów. Czyli przenosimy komunikaty do values\strings.xml. Zdefiniuję również ikonkę okienka, wybiorę z predefiniowanych w systemie (.setIcon(android.R.drawable.ic_dialog_alert)).

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Dialogs</string>
    <string name="confirm">Potwierdź</string>
    <string name="yes">tak</string>
    <string name="no">nie</string>
    <string name="delete_doc">Usunąć wybrany dokument?</string>
    <string name="new_name">Nowa nazwa</string>
</resources>

Jednocześnie, dla osób, które nie lubią wykorzystywać klas anonimowych, zbuduję listenera w ciele klasy. Dzięki temu kod będzie bardziej przejrzysty.
Implementujemy więc opisane zmiany, na początek listener o nazwie dialogYes

private DialogInterface.OnClickListener dialogYes = new DialogInterface.OnClickListener() {        
@Override
public void onClick(DialogInterface dialog, int which) {
    Toast.makeText(Dialogs.this, "Wybrano tak", Toast.LENGTH_LONG).show();
  }
}; 

Teraz czas na nasz AlertDialog, positiveButton odnosi się do listenera dialogYes:

new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.confirm)
.setMessage(R.string.delete_doc)
.setPositiveButton(R.string.yes, dialogYes) 
.setNegativeButton(R.string.no, null)
.show();

Efekt jest podoby, jak w przykładzie pierwszym. Wizualnie, tylko inna ikonka:

Czas na trzeci przykład, tym razem dialog pozwoli na wprowadzenie treści:

Tym razem będzie trudniej. Najpierw musimy zdefiniować odpowiedni layout. Tworzę więc plik w katalogu layout o nazwie alert_dialog_test.xml. Wstawiam do niego TextView (z opisem czynności) oraz EditText (gdzie będą wprowadzane wartości).

Plik alert_dialog_test.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
 
    <TextView 
        android:id="@+id/txtInfo"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_marginLeft="20dip"
        android:layout_marginRight="20dip"
        android:text="Podaj nazwę"
        android:gravity="left"
        android:textAppearance="?android:attr/textAppearanceMedium" />
 
    <EditText
        android:id="@+id/edtFileName"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_marginLeft="20dip"
        android:layout_marginRight="20dip"
        android:scrollHorizontally="true"
        android:autoText="false"
        android:capitalize="none"
        android:maxLines="1"
        android:maxLength="50"
        android:singleLine="true"
        android:gravity="fill_horizontal"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
 

Czas na implementację. Wyciągam widok poprzez LayoutInflater. Z widoku pobieram obiekt EditText. Ustawiam mu początkową treść i zaznaczam wszystko.

LayoutInflater inf = LayoutInflater.from(this);
final View view = inf.inflate(R.layout.alert_dialog_test, null);
final EditText edt = (EditText)view.findViewById(R.id.edtFileName);
edt.setText("Domyślny tekst");
edt.selectAll();
 
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.confirm)
.setMessage(R.string.new_name)
.setView(view)
.setPositiveButton(R.string.yes,new Dialog.OnClickListener() {
 
  @Override
   public void onClick(DialogInterface dialog, int which) {
       Toast.makeText(Dialogs.this, edt.getText(), Toast.LENGTH_LONG).show();
     }
  })
  .setNegativeButton(R.string.no, null)
  .show();

W zdarzeniu onClick wyświetlony zostanie komunikat z wprowadzoną do obietku EditText

W Android SDK mamy dostępne przy rodzaje buttonów, są to NegativeButton, PositiveButton oraz NeutralButton. Każdy z nich może być wykorzystany w przypadku AlertDialog tylko raz. 

Do pobrania źródła projektu Eclipse (50KB).

 

Powiązane artykuły
Android - dostosowanie paska tytułowego (2011-07-12)
Wyznacznik macierzy (2010-12-11)


Komentarze


laplace [2011-07-30 13:18:18]
Faktycznie nie taki diabeł straszny, jak go rysują :-)
Uporządkowałem dzięki artykułowi swoją (chaotyczną dotąd) wiedzę na ten temat.
Pozdrawiam
Bartek [2011-07-30 23:48:44]
Mogłem jeszcze wspomnieć, że zdarzenia do onClick można dopinać do pliku XML. Ale może to na inny post...

Dodaj komentarz:
Autor:*

WWW:

Treść:*

Wprowadź kod zabezpieczający*:


        * - pola wymagane
Kategorie
C# (13)
Inne (6)
Java (3)
Matlab (1)
OpenGL (1)
PHP (2)


Najnowsze wpisy

Ostatnie komentarze