Button i TextView

Jak umieścić przycisk i pole tekstowe w aplikacji Android, jak reagować na kliknięcie oraz jak za pomocą jednej metody obsłużyć wiele przycisków jednocześnie.

Button TextView OnClickListener android:onClick INF.04
Język przykładów:
01

TextView i Button – czym są?

Widoki (widżety)

Wszystko co widzisz na ekranie aplikacji Android to widok (ang. view lub widget). Widoki to elementy interfejsu użytkownika umieszczane w plikach układu XML.

Dwa najczęściej używane widoki to TextView i Button. Oba są klasami języka Java/Kotlin, które dziedziczą po klasie bazowej View.

TextView
wyświetla tekst
+
Button
reaguje na klik
Klasa View
wspólna baza
Interfejs użytk.
to co widzi uczeń
Skąd pochodzi klasa View?

Klasa View pochodzi z pakietu android.view. Każdy widżet – Button, TextView, EditText, CheckBox – jest jej podklasą. Dlatego metody takie jak setVisibility() czy getId() działają na każdym z nich.

Najważniejsze atrybuty XML

Każdy widok definiujemy w pliku res/layout/activity_main.xml. Poniższa tabela pokazuje atrybuty, które będziesz używać najczęściej.

AtrybutCo robiPrzykład wartości
android:idNadaje widokowi unikalną nazwę, przez którą odwołamy się do niego w kodzie@+id/btnKliknij
android:layout_widthSzerokość widokumatch_parent / wrap_content
android:layout_heightWysokość widokumatch_parent / wrap_content
android:textTekst wyświetlany na widoku"Kliknij mnie"
android:textSizeRozmiar czcionki – zawsze podajemy w sp20sp
android:textColorKolor tekstu w notacji szesnastkowej#FFFFFF
android:gravityWyrównanie tekstu wewnątrz widokucenter
android:paddingWewnętrzny odstęp od krawędzi widoku16dp
android:layout_marginZewnętrzny odstęp od sąsiednich widoków8dp
android:onClickNazwa metody uruchamianej po kliknięciu (tylko Button)"napiszCos"
⚠️ sp vs dp – nie mylić!

Rozmiar tekstu podajemy w sp (scale-independent pixels) – uwzględnia ustawienia wielkości czcionki w systemie telefonu. Marginesy i rozmiary widoków podajemy w dp (density-independent pixels). Nigdy nie używamy px.

02

Pierwsza aplikacja z przyciskiem

Zbudujemy prostą aplikację: użytkownik klika przycisk, a w polu tekstowym pojawia się napis. To klasyczny punkt startowy nauki Androida.

Krok 1 – Layout XML

W pliku res/layout/activity_main.xml umieszczamy dwa widoki: TextView do wyświetlania wyniku i Button do kliknięcia. Layout XML jest identyczny dla Java i Kotlin.

res/layout/activity_main.xml XML
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:padding="24dp">

    <!-- Pole tekstowe – początkowo puste, wypełni je kod -->
    <TextView
        android:id="@+id/tvWynik"             <!-- ID do odwołania w kodzie -->
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Naciśnij przycisk..."
        android:textSize="22sp"
        android:gravity="center"
        android:padding="20dp"
        android:layout_marginBottom="32dp" />

    <!-- Przycisk – android:onClick wskazuje metodę w Activity -->
    <Button
        android:id="@+id/btnKliknij"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Kliknij mnie!"
        android:textSize="16sp"
        android:onClick="napiszCos"           <!-- nazwa metody w Activity -->
        android:paddingStart="32dp"
        android:paddingEnd="32dp" />

</LinearLayout>

Krok 2 – jak działa android:onClick?

Atrybut android:onClick="napiszCos" to umowa: „gdy użytkownik kliknie ten przycisk, wywołaj metodę o nazwie napiszCos w pliku aktywności”. Android sam przekazuje do tej metody parametr View v – referencję do przycisku który kliknięto.

Użytkownik klika
Button w aplikacji
Android czyta XML
android:onClick=”napiszCos”
Szuka metody
w MainActivity
Wywołuje napiszCos()
nasz kod działa
Wymagana sygnatura metody

Metoda przypisana przez android:onClick musi spełniać trzy warunki: być public, zwracać void i przyjmować dokładnie jeden parametr typu View. Inaczej aplikacja się nie skompiluje lub wyrzuci wyjątek w czasie działania.

Krok 3 – kod aktywności

W pliku aktywności tworzymy referencję do widoku TextView przez findViewById() i ustawiamy nowy tekst przez setText().

java/MainActivity.java Java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Na razie nic tu nie dodajemy – metoda napiszCos jest niżej
    }

    // Ta metoda uruchomi się gdy użytkownik kliknie przycisk
    // Musi być: public, void, przyjmować View jako parametr
    public void napiszCos(View v) {

        // Szukamy widoku o id "tvWynik" w pliku układu
        TextView tekst = (TextView) findViewById(R.id.tvWynik);

        // Ustawiamy nowy napis
        tekst.setText("Przycisk został kliknięty!");
    }
}
kotlin/MainActivity.kt Kotlin
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    // android:onClick działa tak samo jak w Java
    fun napiszCos(v: View) {

        val tekst = findViewById<TextView>(R.id.tvWynik)

        // Kotlin: właściwość .text zamiast setText()
        tekst.text = "Przycisk został kliknięty!"
    }
}
Kotlin: właściwość zamiast metody

W Kotlinie zamiast setText("...") piszemy .text = "...". Zamiast getText() piszemy .text. To nie są nowe metody – Kotlin automatycznie tłumaczy dostęp do właściwości na wywołanie gettera/settera.

Co to jest R.id.tvWynik?

Android podczas kompilacji czyta plik XML i dla każdego atrybutu android:id="@+id/cokolwiek" generuje stałą liczbową w klasie R. Dlatego R.id.tvWynik to po prostu liczba identyfikująca nasz widok. findViewById() przeszukuje aktywny układ i zwraca widok o podanym numerze.

03

Wiele przycisków – jedna wspólna metoda

W rzeczywistych aplikacjach mamy wiele przycisków. Zamiast pisać osobną metodę dla każdego z nich, możemy użyć jednej wspólnej metody, która sprawdza który przycisk został kliknięty.

Dlaczego jedna metoda jest lepsza?

❌ Osobna metoda dla każdego

Każdy przycisk ma swój android:onClick. Działa, ale gdy mamy 5 przycisków – piszemy 5 metod z podobnym kodem. Trudne w utrzymaniu.

✅ Jedna wspólna metoda

Wszystkie przyciski wskazują na tę samą metodę. Wewnątrz niej sprawdzamy który przycisk kliknięto. Kod w jednym miejscu, łatwy do zmiany.

Klucz: parametr View v i metoda getId()

Każda metoda onClick otrzymuje parametr View v – to referencja do widoku który kliknięto. Metoda v.getId() zwraca liczbowy identyfikator tego widoku. Porównując go z R.id.nazwaWidoku wiemy dokładnie który przycisk kliknął użytkownik.

Krok 1 – przypisanie tej samej metody w XML

Wszystkim przyciskom nadajemy tę samą nazwę w atrybucie android:onClick.

res/layout/activity_main.xml XML
<LinearLayout ...orientation="vertical" android:padding="24dp">

    <TextView
        android:id="@+id/tvWynik"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Wybierz działanie"
        android:textSize="24sp"
        android:gravity="center"
        android:padding="20dp"
        android:layout_marginBottom="24dp" />

    <!-- Wszystkie trzy przyciski wskazują na TĘ SAMĄ metodę -->
    <Button
        android:id="@+id/btnDodaj"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Dodaj"
        android:onClick="kliknietoPrzycisk" />

    <Button
        android:id="@+id/btnOdejmij"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Odejmij"
        android:onClick="kliknietoPrzycisk" />

    <Button
        android:id="@+id/btnCzysc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Wyczyść"
        android:onClick="kliknietoPrzycisk" />

</LinearLayout>

Krok 2 – jedna metoda z instrukcją switch

W metodzie kliknietoPrzycisk pobieramy id klikniętego widoku przez v.getId() i sprawdzamy który to przycisk instrukcją switch.

java/MainActivity.java Java
public class MainActivity extends AppCompatActivity {

    // Zmienna przechowuje aktualny wynik – zadeklarowana w klasie
    // aby była dostępna w każdej metodzie
    int wynik = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // JEDNA metoda obsługuje TRZY przyciski
    public void kliknietoPrzycisk(View v) {

        // Pobieramy id klikniętego przycisku
        int id = v.getId();

        // Sprawdzamy który przycisk kliknięto
        switch (id) {
            case R.id.btnDodaj:
                wynik = wynik + 1;
                break;
            case R.id.btnOdejmij:
                wynik = wynik - 1;
                break;
            case R.id.btnCzysc:
                wynik = 0;
                break;
        }

        // Aktualizujemy widok TextView
        TextView tvWynik = (TextView) findViewById(R.id.tvWynik);
        tvWynik.setText("Wynik: " + wynik);
    }
}
kotlin/MainActivity.kt Kotlin
class MainActivity : AppCompatActivity() {

    // Kotlin: var zamiast int (typ wywnioskowany)
    var wynik = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun kliknietoPrzycisk(v: View) {

        // Kotlin: when zamiast switch – czytelniejszy zapis
        when (v.id) {
            R.id.btnDodaj   -> wynik++
            R.id.btnOdejmij -> wynik--
            R.id.btnCzysc   -> wynik = 0
        }

        val tvWynik = findViewById<TextView>(R.id.tvWynik)
        // String template: $wynik wstawia wartość zmiennej
        tvWynik.text = "Wynik: $wynik"
    }
}
Kotlin: when zamiast switch

W Kotlinie switch zastępuje wyrażenie when. Jest bardziej czytelne – nie trzeba pisać break po każdej opcji. Zapis R.id.btnDodaj -> wynik++ to jeden wiersz zamiast czterech.

Dlaczego zmienna wynik jest w klasie, nie w metodzie?

Gdyby wynik był deklarowany wewnątrz metody kliknietoPrzycisk(), resetowałby się do zera przy każdym kliknięciu. Deklarując go jako pole klasy (field) zachowuje wartość między kolejnymi wywołaniami metody.

04

Alternatywa: setOnClickListener w kodzie

Drugi sposób obsługi kliknięć to rejestracja nasłuchiwacza (listenera) bezpośrednio w kodzie Activity, bez użycia atrybutu android:onClick w XML.

To podejście jest używane gdy nie chcemy modyfikować pliku XML, albo gdy tworzymy widoki dynamicznie w kodzie (np. przyciski generowane w pętli).

java/MainActivity.java – setOnClickListener Java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Pobieramy referencje do widoków
    TextView tvWynik  = (TextView) findViewById(R.id.tvWynik);
    Button   btnDodaj  = (Button)   findViewById(R.id.btnDodaj);
    Button   btnOdejmij = (Button)  findViewById(R.id.btnOdejmij);

    // Jedna lambda (listener) dla obu przycisków – ten sam trick z getId()
    View.OnClickListener listener = v -> {
        if (v.getId() == R.id.btnDodaj)  wynik++;
        if (v.getId() == R.id.btnOdejmij) wynik--;
        tvWynik.setText("Wynik: " + wynik);
    };

    btnDodaj.setOnClickListener(listener);
    btnOdejmij.setOnClickListener(listener);
}
kotlin/MainActivity.kt – setOnClickListener Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val tvWynik   = findViewById<TextView>(R.id.tvWynik)
    val btnDodaj  = findViewById<Button>(R.id.btnDodaj)
    val btnOdejmij = findViewById<Button>(R.id.btnOdejmij)

    // Kotlin: zwarta lambda przypisana do zmiennej
    val listener = View.OnClickListener { v ->
        when (v.id) {
            R.id.btnDodaj   -> wynik++
            R.id.btnOdejmij -> wynik--
        }
        tvWynik.text = "Wynik: $wynik"
    }

    btnDodaj.setOnClickListener(listener)
    btnOdejmij.setOnClickListener(listener)
}
05

Kiedy co stosować?

Metoda Jak działa Kiedy używać Uwaga
android:onClick w XML Nazwa metody wpisana w XML – Android sam ją wywołuje Przyciski zdefiniowane w XML, prosta logika Metoda musi być public void NazwaMetody(View v)
Jedna metoda + switch(v.getId()) Wszystkie przyciski wskazują na tę samą metodę; switch rozróżnia który kliknięto Wiele przycisków w jednym Activity – zalecane Zmienna wynik musi być polem klasy, nie lokalną
setOnClickListener w kodzie Listener rejestrujemy programistycznie w onCreate() Widoki tworzone dynamicznie; brak android:onClick w XML Nie wymaga modyfikacji XML – elastyczniejsze
Rekomendacja dla uczniów INF.04

Na zajęciach i egzaminie najczęściej spotkasz metodę z android:onClick – to najprostsze i najbardziej czytelne podejście. Gdy masz wiele przycisków, przypisz im tę samą nazwę metody i użyj switch/when w środku. setOnClickListener wprowadź gdy opanujesz podstawy.

06

Podsumowanie pojęć

Pojęcie Java Kotlin Co robi?
Pobierz widok (TextView) findViewById(R.id.x) findViewById<TextView>(R.id.x) Łączy zmienną z widokiem z XML
Ustaw tekst tv.setText("napis") tv.text = "napis" Zmienia napis w TextView lub Button
Pobierz tekst tv.getText().toString() tv.text.toString() Odczytuje aktualny napis z widoku
Id klikniętego v.getId() v.id Zwraca liczbowy identyfikator widoku
Sprawdź który switch(v.getId()) { case R.id.x: ... } when(v.id) { R.id.x -> ... } Rozgałęzienie na podstawie ID
Metoda kliknięcia public void nazwa(View v) { } fun nazwa(v: View) { } Wymagana sygnatura dla android:onClick
String z liczbą "Wynik: " + wynik "Wynik: $wynik" Składanie łańcucha z wartością zmiennej
Zadanie

Zadanie dla uczniów

Prosta zgadywanka liczb

  • Stwórz aplikację z TextView wyświetlającym pytanie: „Ile to 7 × 8?”
  • Dodaj trzy przyciski z odpowiedziami: 54, 56, 64
  • Wszystkie trzy przyciski mają wskazywać na jedną wspólną metodę sprawdzOdpowiedz
  • Wewnątrz metody użyj switch (Java) lub when (Kotlin) z v.getId()
  • Po kliknięciu poprawnej odpowiedzi: TextView wyświetla „✅ Dobrze! 7 × 8 = 56″
  • Po kliknięciu błędnej odpowiedzi: wyświetla „❌ Niepoprawnie, spróbuj jeszcze raz”

⭐ Bonus 1: zmień kolor tekstu w TextView – zielony dla poprawnej, czerwony dla błędnej odpowiedzi (setTextColor())

⭐⭐ Bonus 2: dodaj czwarty przycisk Reset, który przywraca pierwotne pytanie i neutralny kolor tekstu

⭐⭐⭐ Bonus Kotlin: cały kod przepisz w Kotlinie używając when, string templates ($zmienna) i właściwości zamiast setterów