Okna dialogowe (okna alertów)
Proste okna dialogowe (tak zwane okna modalne) w systemie Android są odpowiednikiem okien dialogowych klasy MessageBox z systemu Windows. W Androidzie jest to klasa AlertDialog. Ten typ okna komunikatów z ewentualnym prostym dialogiem wyboru opcji, pokazuje pewne informacje prosząc użytkownika o podjęcie działania.
Istnieją trzy podstawowe komponenty tworzące okno dialogowe alertów.
- tekst tytułu
- wiadomość tekstowa
- przyciski
Przyciski są w trzech rodzajach: dodatni (PositiveButton), ujemny (NegativeButton) i neutralny (NeutralButton)
Do utworzenia okna dialogowego (AlertDialog) używa się metody Builder, której parametrem jest kontekst bieżącej aktywności
Wskazówka:
val oknoAlertu=AlertDialog.Builder(this)
Tak wywołany konstruktor używa domyślnego motywu okna dialogowego alertu.
Metody dialogu alertów
Przykładowe metody, które można użyć w AlertDialog.
- setTitle - ustaw tytuł
- setMessage - ustaw wiadomość
- setIcon - ustawIkonę
- setCustomTitle - tutaj możesz przekazać niestandardowy widok, który zostanie umieszczony zamiast części tytułowej w oknie dialogowym alertu.
- setPositiveButton - Podajemy tutaj nazwę ciągu znaków oraz metodę wywołania zwrotnego kliknięcia przycisku.
- setView - służy do dodawania niestandardowego widoku w oknie dialogowym alertu.
- setList - służy do ustawiania tablicy ciągów znaków, które będą wyświetlane w formie listy.
- setMultiChoiceList - ponownie możemy ustawić tablicę, ale tym razem możemy wybrać wiele pozycji z Listy dzięki CheckBox.
- setPositiveButtonIcon - ustaw ikonę obok przycisku
- show() - służy do wyświetlania AlertDialog
- setDismissListener - w tym miejscu możesz ustawić logikę uruchamianą w przypadku odrzucenia okna dialogowego alertu.
- setShowListener - ustaw logikę, która będzie uruchamiana po zamknięciu okna alertu.
- setCancelable - wymaga wartości logicznej. Domyślnie wszystkie okna dialogowe alertów można anulować po kliknięciu przycisku lub dotknięciu na zewnątrz. Jeśli ta metoda jest ustawiona na false, musisz jawnie anulować okno dialogowe za pomocą metody dialog.cancel().
Projekt aplikacji wykorzystującej standardowe okna komunikatów
Celem jest przygotowanie aplikacji mobilnej, która będzie zawierać trzy okna dialogowe wyświetlające licznik kliknięć, zwiększać licznik kliknięć, zamykać aplikację.
Utwórz pusty projekt. W widoku układu wykorzystaj jedna kontrolkę typu TextView i pięć kontrolek typu Button. Kontrolkom przypisz odpowiedni tekst.
Zawartość pliku XML układu widoku
Wskazówka:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="44dp"
android:layout_marginEnd="24dp"
android:text="Licznik kliknięć"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginTop="100dp"
android:layout_marginEnd="160dp"
android:text="Klikaj"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="160dp"
android:text="Pokaż komunikat (wersja 1)"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.503"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button1" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="160dp"
android:text="Pokaż komunikat (wersja 2)"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="160dp"
android:text="Zamknij"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button3" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="36dp"
android:layout_marginEnd="29dp"
android:text="Zamknij z okna dialogowego"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.507"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button4" />
</androidx.constraintlayout.widget.ConstraintLayout>
Zliczanie kliknięć
W głównym pliku projektu aplikacji (MainActivity.kt) deklarujemy licznik kliknięć
Wskazówka:
class MainActivity : AppCompatActivity() {
var licznik=0
override fun onCreate(savedInstanceState: Bundle?) {
Dodajemy dwie funkcje. Jedna z funkcji będzie zamykać aplikację, a druga zliczać kliknięcia.
Wskazówka:
private fun Zamknij(){
this.finish()
System.exit(0)
}
private fun Licznik(i:Int):Int{
return i+1
}
W funkcji onCreate() obsłużymy obie funkcje ustawiając słuchaczy dla przycisku klikania i zamykania aplikacji
Wskazówka:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//słuchacz dla przycisku zamknij
val bt4=findViewById<Button>(R.id.button4)
bt4.setOnClickListener { Zamknij() }
//słuchacz dla przycisku klikania
val bt1=findViewById<Button>(R.id.button1)
bt1.setOnClickListener {
licznik=Licznik(licznik)
//pokaz ilosc klikniec
val tv=findViewById<TextView>(R.id.textView)
tv.setText("Licznik kliknięć: "+licznik)
}
}
Uruchom aplikację i sprawdź działanie.
Prosty komunikat zliczeń kliknięć
Do drugiego klawisza przypiszemy komunikat, który będzie zawierać tytuł komunikatu, informację o kliknięciach oraz jeden przycisk typu PositiveButton z napisem Zamknij
Okno tworzonego komunikatu opiszemy poniższą funkcją.
Wskazówka:
private fun KomunikatWersja1(i:Int){
val oknoAlertu=AlertDialog.Builder(this)
oknoAlertu.setTitle("Komunikat wersja 1")
oknoAlertu.setMessage("Licznik kliknięć: "+i)
//klikniecie automatycznie zamyka okno dialogowe
oknoAlertu.setPositiveButton("Zamknij",null)
oknoAlertu.show()
}
Działanie funkcji jest proste. Pierwsza linijka inicjuje okno, kolejne trzy ustawiają tytuł, treść wiadomości, ustawienie przycisku. Kliknięcia są przekazywane do funkcji przez jej argument. Wywołani tej funkcji wykonamy przez słuchacza kliknięć kolejnego przycisku Button.
Do funkcji onCreate() dopisujemy poniższy kod.
Wskazówka:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//słuchacz dla przycisku zamknij
val bt4=findViewById<Button>(R.id.button4)
bt4.setOnClickListener { Zamknij() }
//słuchacz dla przycisku klikania
val bt1=findViewById<Button>(R.id.button1)
bt1.setOnClickListener {
licznik=Licznik(licznik)
//pokaz ilosc klikniec
val tv=findViewById<TextView>(R.id.textView)
tv.setText("Licznik kliknięć: "+licznik)
}
//słuchacz dla przycisku komunikatu wersja 1
val bt2=findViewById<Button>(R.id.button2)
bt2.setOnClickListener {
KomunikatWersja1(licznik)
}
}
Skompiluj program i sprawdź efekt działania.
Komunikat z wykonaniem wewnętrznej instrukcji
Druga wersja komunikatu zostanie wzbogacona o wykonanie dodatkowej instrukcji w momencie wybrania przycisku PositiveButton. Ta dodatkowa instrukcja zwiększy licznik klikania.
Wskazówka:
private fun KomunikatWersja2(i:Int){
val oknoAlertu=AlertDialog.Builder(this)
oknoAlertu.setTitle("Komunikat wersja 2")
oknoAlertu.setMessage("Licznik kliknięć: "+i)
//klikniecie automatycznie zamyka okno dialogowe
//i zwieksza licznik o 1
oknoAlertu.setPositiveButton("Zamknij i zwiększ licznik"){d,id->
licznik=Licznik(licznik)
val tv=findViewById<TextView>(R.id.textView)
tv.setText("Licznik kliknięć zwiekszono z zamknięcia okna dialogowego: "+licznik)
}
oknoAlertu.show()
}
Zauważ, że wykonanie dodatkowych instrukcji po wybraniu przycisku typu PositiveButton wykorzystuj wyrażenie typu lambda do implementacji detektora (słuchacza) zdarzenia Click
Wskazówka:
oknoAlertu.setPositiveButton("Zamknij i zwiększ licznik")
{d,id->/*instrukcje*/}
Parametr d reprezentuje uchwyt do okna alertu, a parametr id reprezentuje serię instrukcji.
Funkcję z nowym komunikatem wywołamy w metodzie onCreate() przy kliknięciu w trzecią kontrolkę Button
Wskazówka:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//słuchacz dla przycisku zamknij
val bt4=findViewById<Button>(R.id.button4)
bt4.setOnClickListener { Zamknij() }
//słuchacz dla przycisku klikania
val bt1=findViewById<Button>(R.id.button1)
bt1.setOnClickListener {
licznik=Licznik(licznik)
//pokaz ilosc klikniec
val tv=findViewById<TextView>(R.id.textView)
tv.setText("Licznik kliknięć: "+licznik)
}
//słuchacz dla przycisku komunikatu wersja 1
val bt2=findViewById<Button>(R.id.button2)
bt2.setOnClickListener {
KomunikatWersja1(licznik)
}
//słuchacz dla przycisku komunikatu wersja 2
val bt3=findViewById<Button>(R.id.button3)
bt3.setOnClickListener {
KomunikatWersja2(licznik)
}
}
Skompiluj program i sprawdź efekt działania
Zamknięcie aplikacji z okna dialogowego
Trzecia wersja okna dialogowego będzie zawierać dwa przyciski. Jeden typu PositiveButton, który zamknie aplikację. Drugi przycisk jest typu NegativeButton. Wybór tego przycisku zamyka tylko okno dialogowe.
Wskazówka:
private fun KomunikatWersja3(){
val oknoAlertu=AlertDialog.Builder(this)
oknoAlertu.setTitle("Komunikat wersja 3")
oknoAlertu.setMessage("Czy zakończyć aplikację?")
//klikniecie automatycznie zamyka okno dialogowe
//i całą aplikację
oknoAlertu.setPositiveButton("Tak"){d,id->
Zamknij()
}
//klikniecie zamyka tylko okno dialogowe
oknoAlertu.setNegativeButton("Nie",null)
oknoAlertu.show()
}
Wywołanie tego komunikatu zrealizujemy ostatnim przyciskiem typu Button. Do metody onCreate() dopisujemy obsługę ostatniej kontrolki Button.
Wskazówka:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//słuchacz dla przycisku zamknij
val bt4=findViewById<Button>(R.id.button4)
bt4.setOnClickListener { Zamknij() }
//słuchacz dla przycisku klikania
val bt1=findViewById<Button>(R.id.button1)
bt1.setOnClickListener {
licznik=Licznik(licznik)
//pokaz ilosc klikniec
val tv=findViewById<TextView>(R.id.textView)
tv.setText("Licznik kliknięć: "+licznik)
}
//słuchacz dla przycisku komunikatu wersja 1
val bt2=findViewById<Button>(R.id.button2)
bt2.setOnClickListener {
KomunikatWersja1(licznik)
}
//słuchacz dla przycisku komunikatu wersja 2
val bt3=findViewById<Button>(R.id.button3)
bt3.setOnClickListener {
KomunikatWersja2(licznik)
}
//słuchacz dla przycisku zamknij z okna dialogowego
val bt5=findViewById<Button>(R.id.button5)
bt5.setOnClickListener {
KomunikatWersja3()
}
}
Sprawdź działanie aplikacji.
Pełny kod rozwiązania
Wskazówka:
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
var licznik=0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//słuchacz dla przycisku zamknij
val bt4=findViewById<Button>(R.id.button4)
bt4.setOnClickListener { Zamknij() }
//słuchacz dla przycisku klikania
val bt1=findViewById<Button>(R.id.button1)
bt1.setOnClickListener {
licznik=Licznik(licznik)
//pokaz ilosc klikniec
val tv=findViewById<TextView>(R.id.textView)
tv.setText("Licznik kliknięć: "+licznik)
}
//słuchacz dla przycisku komunikatu wersja 1
val bt2=findViewById<Button>(R.id.button2)
bt2.setOnClickListener {
KomunikatWersja1(licznik)
}
//słuchacz dla przycisku komunikatu wersja 2
val bt3=findViewById<Button>(R.id.button3)
bt3.setOnClickListener {
KomunikatWersja2(licznik)
}
//słuchacz dla przycisku zamknij z okna dialogowego
val bt5=findViewById<Button>(R.id.button5)
bt5.setOnClickListener {
KomunikatWersja3()
}
}
private fun Zamknij(){
this.finish()
System.exit(0)
}
private fun Licznik(i:Int):Int{
return i+1
}
private fun KomunikatWersja1(i:Int){
val oknoAlertu=AlertDialog.Builder(this)
oknoAlertu.setTitle("Komunikat wersja 1")
oknoAlertu.setMessage("Licznik kliknięć: "+i)
//klikniecie automatycznie zamyka okno dialogowe
oknoAlertu.setPositiveButton("Zamknij",null)
oknoAlertu.show()
}
private fun KomunikatWersja2(i:Int){
val oknoAlertu=AlertDialog.Builder(this)
oknoAlertu.setTitle("Komunikat wersja 2")
oknoAlertu.setMessage("Licznik kliknięć: "+i)
//klikniecie automatycznie zamyka okno dialogowe
//i zwieksza licznik o 1
oknoAlertu.setPositiveButton("Zamknij i zwiększ licznik"){d,id->
licznik=Licznik(licznik)
val tv=findViewById<TextView>(R.id.textView)
tv.setText("Licznik kliknięć zwiekszono z zamknięcia okna dialogowego: "+licznik)
}
oknoAlertu.show()
}
private fun KomunikatWersja3(){
val oknoAlertu=AlertDialog.Builder(this)
oknoAlertu.setTitle("Komunikat wersja 3")
oknoAlertu.setMessage("Czy zakończyć aplikację?")
//klikniecie automatycznie zamyka okno dialogowe
//i całą aplikację
oknoAlertu.setPositiveButton("Tak"){d,id->
Zamknij()
}
//klikniecie zamyka tylko okno dialogowe
oknoAlertu.setNegativeButton("Nie",null)
oknoAlertu.show()
}
}