EditText – pole tekstowe

Jak pobierać tekst wpisany przez użytkownika, ustawiać typ klawiatury, walidować dane oraz reagować na każdą zmianę tekstu w czasie rzeczywistym.

EditText getText() inputType TextWatcher INF.04
Język przykładów:
01

Czym jest EditText?

EditText to pole tekstowe w którym użytkownik może wpisywać tekst. To podstawowa kontrolka każdego formularza – logowania, rejestracji, wyszukiwania, wypełniania danych.

EditText dziedziczy po TextView, który z kolei dziedziczy po View. Oznacza to że wszystkie metody i atrybuty znane z TextView działają też na EditTextsetText(), setTextColor(), setVisibility() i inne.

View
klasa bazowa wszystkich widoków
TextView
wyświetla tekst
EditText
wyświetla i przyjmuje tekst

TextView

Tylko wyświetla tekst. Użytkownik nie może nic wpisać. Programista zmienia tekst przez setText().

EditText

Wyświetla tekst i pozwala użytkownikowi wpisywać. Programista odczytuje wpisany tekst przez getText().

02

Atrybuty XML

Podstawowe atrybuty

res/layout/activity_main.xml – kompletny EditText XML
<EditText
    android:id="@+id/etImie"               <!-- ID do odwołania w kodzie -->
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:hint="Wpisz imię"               <!-- tekst podpowiedzi (szary, znika po kliknięciu) -->
    android:text="Jan"                     <!-- wartość domyślna (opcjonalne) -->

    android:inputType="textPersonName"    <!-- typ klawiatury (opisane niżej) -->

    android:maxLength="30"                 <!-- maksymalna liczba znaków -->
    android:maxLines="1"                   <!-- ogranicz do jednej linii -->
    android:singleLine="true"              <!-- Enter nie przechodzi do nowej linii -->

    android:textSize="16sp"
    android:padding="12dp"
    android:layout_marginBottom="12dp" />
hint vs text – różnica

android:hint to podpowiedź – szary tekst widoczny gdy pole jest puste, znika automatycznie gdy użytkownik zacznie pisać. android:text to tekst domyślny który pojawi się w polu od razu – użytkownik musi go ręcznie usunąć żeby wpisać coś innego. Na formularzach prawie zawsze używamy hint, nie text.

inputType – typ klawiatury

Atrybut android:inputType informuje Android jakiego typu dane będą wpisywane. Android na tej podstawie dobiera odpowiednią klawiaturę i może stosować dodatkowe formatowanie.

Wartość inputTypeKlawiat. która się pojawiKiedy używać
textStandardowa tekstowaDowolny tekst bez ograniczeń
textPersonNameTekstowa, wielka litera na starcieImię, nazwisko
textEmailAddressTekstowa z widocznym @Adres e-mail
textPasswordTekstowa, znaki zastąpione kropkamiHasło
numberNumeryczna (tylko cyfry)Liczba całkowita
numberDecimalNumeryczna z przecinkiemLiczba z częścią dziesiętną
numberPasswordNumeryczna, cyfry zastąpione kropkamiPIN
phoneNumeryczna z +, *, #Numer telefonu
textMultiLineTekstowa z Enter przechodzącym do nowej liniiNotatka, wiadomość
inputType nie jest walidacją

Ustawienie inputType="number" pokazuje klawiaturę numeryczną, ale nie gwarantuje że pole zawiera liczbę. Użytkownik może np. wkleić tekst ze schowka. Zawsze waliduj dane w kodzie przed ich użyciem.

03

Odczyt tekstu w kodzie

getText().toString()

Tekst wpisany przez użytkownika pobieramy metodą getText(). Zwraca ona obiekt typu Editable – dlatego zawsze dopisujemy .toString() żeby otrzymać zwykły String.

java/MainActivity.java – odczyt tekstu Java
EditText etImie = findViewById(R.id.etImie);

// getText() zwraca Editable – nie String!
// Dlatego dodajemy .toString() aby dostać String
String imie = etImie.getText().toString();

// Jeśli pole ma inputType="number" – konwertujemy na int
EditText etWiek = findViewById(R.id.etWiek);
int wiek = Integer.parseInt(etWiek.getText().toString());

// Jeśli pole ma inputType="numberDecimal"
EditText etCena = findViewById(R.id.etCena);
double cena = Double.parseDouble(etCena.getText().toString());
kotlin/MainActivity.kt – odczyt tekstu Kotlin
val etImie: EditText = findViewById(R.id.etImie)

// Kotlin: .text zwraca Editable – .toString() konwertuje na String
val imie = etImie.text.toString()

// Konwersja na liczbę
val wiek  = etWiek.text.toString().toInt()
val cena  = etCena.text.toString().toDouble()
parseInt() rzuci wyjątek gdy pole jest puste

Wywołanie Integer.parseInt("") lub "".toInt() zakończy się wyjątkiem NumberFormatException i crashem aplikacji. Zanim spróbujesz skonwertować tekst na liczbę – zawsze sprawdź czy pole nie jest puste. Zobaczysz jak to zrobić w następnej sekcji.

Walidacja – sprawdzenie czy pole jest puste

Walidacja to sprawdzenie czy dane wpisane przez użytkownika są poprawne przed ich użyciem. Najprostszy i najczęstszy przypadek: czy pole nie jest puste.

java/MainActivity.java – walidacja przed odczytem Java
String imie = etImie.getText().toString();

// trim() usuwa spacje z początku i końca – sam spacja to też "puste" pole
if (imie.trim().isEmpty()) {
    // Pole jest puste – pokaż komunikat
    etImie.setError("To pole jest wymagane");  // czerwona ikonka błędu na polu
    return;  // zatrzymaj wykonanie metody
} else {
    // Pole ma tekst – możemy go bezpiecznie użyć
    tvWynik.setText("Witaj, " + imie);
}

// Walidacja liczby – sprawdź najpierw String, potem parsuj
String wiekTekst = etWiek.getText().toString().trim();
if (wiekTekst.isEmpty()) {
    etWiek.setError("Podaj wiek");
    return;
}
int wiek = Integer.parseInt(wiekTekst);  // teraz bezpieczne
kotlin/MainActivity.kt – walidacja przed odczytem Kotlin
val imie = etImie.text.toString().trim()

if (imie.isEmpty()) {
    etImie.setError("To pole jest wymagane")
    return
} else {
    tvWynik.text = "Witaj, $imie"
}

// Walidacja liczby
val wiekTekst = etWiek.text.toString().trim()
if (wiekTekst.isEmpty()) {
    etWiek.setError("Podaj wiek")
    return
}
val wiek = wiekTekst.toInt()  // teraz bezpieczne
setError() – wbudowany komunikat błędu

Metoda setError("komunikat") wyświetla czerwoną ikonkę po prawej stronie pola EditText z dymkiem zawierającym podany tekst. To wbudowany mechanizm walidacji Androida – nie trzeba tworzyć osobnego TextView na komunikaty błędów. Wywołanie setError(null) usuwa błąd.

04

Operacje na EditText w kodzie

Ustawienie tekstu

Metoda setText() działa tak samo jak w TextView – bo EditText dziedziczy po TextView. Możesz wpisać tekst do pola programistycznie – np. aby wypełnić formularz domyślnymi wartościami.

java/MainActivity.java Java
// Wpisz tekst do pola
etImie.setText("Jan Kowalski");

// Przesuń kursor na koniec tekstu
etImie.setSelection(etImie.getText().length());

// Zaznacz cały tekst (przydatne żeby użytkownik od razu mógł zastąpić)
etImie.selectAll();
kotlin/MainActivity.kt Kotlin
etImie.setText("Jan Kowalski")

// Przesuń kursor na koniec
etImie.setSelection(etImie.text.length)

// Zaznacz cały tekst
etImie.selectAll()

Czyszczenie pola

Dwa równoważne sposoby wyczyszczenia zawartości pola – oba robią to samo:

java/MainActivity.java – czyszczenie EditText Java
// Sposób 1: setText z pustym Stringiem
etImie.setText("");

// Sposób 2: getText().clear() – czyści obiekt Editable
etImie.getText().clear();

// Po wyczyszczeniu można przywrócić fokus (kursor do pola)
etImie.requestFocus();
kotlin/MainActivity.kt – czyszczenie EditText Kotlin
// Sposób 1
etImie.setText("")

// Sposób 2
etImie.text.clear()

etImie.requestFocus()

Zmiana wyglądu w kodzie

Ponieważ EditText dziedziczy po TextView, wszystkie metody zmiany wyglądu działają identycznie:

java/MainActivity.java – wygląd EditText Java
// Aktywuj / dezaktywuj pole (false = szare, nieaktywne)
etImie.setEnabled(false);
etImie.setEnabled(true);

// Zmień podpowiedź hint w kodzie
etImie.setHint("Nowa podpowiedź");

// Zmień kolor tekstu
etImie.setTextColor(Color.parseColor("#E6EDF3"));

// Ukryj / pokaż (dziedziczone z View)
etImie.setVisibility(View.GONE);
etImie.setVisibility(View.VISIBLE);

// Usuń komunikat błędu (po poprawnym wpisaniu)
etImie.setError(null);
kotlin/MainActivity.kt – wygląd EditText Kotlin
// Aktywuj / dezaktywuj pole
etImie.isEnabled = false
etImie.isEnabled = true

// Zmień podpowiedź hint
etImie.setHint("Nowa podpowiedź")

// Ukryj / pokaż
etImie.visibility = View.GONE
etImie.visibility = View.VISIBLE

// Usuń komunikat błędu
etImie.setError(null)
05

Pełny przykład – formularz z walidacją

Łączymy wszystko razem: formularz z dwoma polami (imię i wiek), przycisk który pobiera dane, waliduje je i wyświetla wynik.

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:padding="24dp">

    <EditText
        android:id="@+id/etImie"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Imię"
        android:inputType="textPersonName"
        android:maxLength="30"
        android:layout_marginBottom="12dp" />

    <EditText
        android:id="@+id/etWiek"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Wiek"
        android:inputType="number"
        android:maxLength="3"
        android:layout_marginBottom="24dp" />

    <Button
        android:id="@+id/btnZatwierdz"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Zatwierdź"
        android:layout_marginBottom="24dp" />

    <TextView
        android:id="@+id/tvWynik"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Wynik pojawi się tutaj"
        android:textSize="18sp"
        android:gravity="center"
        android:padding="16dp" />

</LinearLayout>
java/MainActivity.java – kompletna klasa Java
public class MainActivity extends AppCompatActivity {

    EditText etImie, etWiek;
    Button   btnZatwierdz;
    TextView tvWynik;

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

    public void initUI() {
        etImie       = findViewById(R.id.etImie);
        etWiek       = findViewById(R.id.etWiek);
        btnZatwierdz = findViewById(R.id.btnZatwierdz);
        tvWynik      = findViewById(R.id.tvWynik);

        btnZatwierdz.setOnClickListener(v -> {
            zatwierdz();
        });
    }

    public void zatwierdz() {
        String imie     = etImie.getText().toString().trim();
        String wiekTekst = etWiek.getText().toString().trim();

        // Walidacja pola imię
        if (imie.isEmpty()) {
            etImie.setError("Podaj imię");
            return;
        }

        // Walidacja pola wiek
        if (wiekTekst.isEmpty()) {
            etWiek.setError("Podaj wiek");
            return;
        }

        // Bezpieczna konwersja – pole nie jest puste
        int wiek = Integer.parseInt(wiekTekst);

        // Usuń błędy jeśli były
        etImie.setError(null);
        etWiek.setError(null);

        // Wyświetl wynik
        tvWynik.setText("Imię: " + imie + ", Wiek: " + wiek);
    }
}
kotlin/MainActivity.kt – kompletna klasa Kotlin
class MainActivity : AppCompatActivity() {

    lateinit var etImie      : EditText
    lateinit var etWiek      : EditText
    lateinit var btnZatwierdz: Button
    lateinit var tvWynik     : TextView

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

    fun initUI() {
        etImie       = findViewById(R.id.etImie)
        etWiek       = findViewById(R.id.etWiek)
        btnZatwierdz = findViewById(R.id.btnZatwierdz)
        tvWynik      = findViewById(R.id.tvWynik)

        btnZatwierdz.setOnClickListener { zatwierdz() }
    }

    fun zatwierdz() {
        val imie     = etImie.text.toString().trim()
        val wiekTekst = etWiek.text.toString().trim()

        if (imie.isEmpty()) {
            etImie.setError("Podaj imię")
            return
        }

        if (wiekTekst.isEmpty()) {
            etWiek.setError("Podaj wiek")
            return
        }

        val wiek = wiekTekst.toInt()

        etImie.setError(null)
        etWiek.setError(null)

        tvWynik.text = "Imię: $imie, Wiek: $wiek"
    }
}
06

TextWatcher – reagowanie na zmianę tekstu

Do tej pory reagowaliśmy na kliknięcie przycisku. TextWatcher pozwala reagować na każdą zmianę tekstu w polu EditText – na bieżąco, bez klikania przycisku. Przydatny do wyszukiwania w czasie rzeczywistym, liczenia znaków, bieżącej walidacji.

TextWatcher – trzy metody

Interfejs TextWatcher wymaga implementacji trzech metod:
beforeTextChanged() – wywoływana przed zmianą (rzadko używana)
onTextChanged() – wywoływana w trakcie zmiany, otrzymuje nową zawartość
afterTextChanged() – wywoływana po zmianie, najczęściej używana

java/MainActivity.java – TextWatcher Java
etImie.addTextChangedListener(new TextWatcher() {

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // Wywoływana PRZED zmianą – rzadko używana
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // s to aktualny tekst w polu po zmianie
        tvWynik.setText("Wpisujesz: " + s.toString());
    }

    @Override
    public void afterTextChanged(Editable s) {
        // Najczęściej używana – s to Editable z aktualnym tekstem
        // Usuń błąd gdy użytkownik zacznie poprawiać
        if (!s.toString().trim().isEmpty()) {
            etImie.setError(null);
        }
    }
});
kotlin/MainActivity.kt – TextWatcher Kotlin
etImie.addTextChangedListener(object : TextWatcher {

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        // rzadko używana
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        tvWynik.text = "Wpisujesz: ${s.toString()}"
    }

    override fun afterTextChanged(s: Editable?) {
        // Usuń błąd gdy użytkownik zacznie poprawiać
        if (!s.toString().trim().isEmpty()) {
            etImie.setError(null)
        }
    }
})
Praktyczne zastosowania TextWatcher

Licznik znaków („120 znaków pozostało”), przycisk Zatwierdź aktywny dopiero gdy wszystkie pola są wypełnione, podpowiedzi przy wyszukiwaniu, walidacja hasła w czasie rzeczywistym (wymagana długość, duże litery). Wszystkie te przypadki wymagają TextWatcher – przycisk wyzwala akcję, ale nie aktualizuje UI na bieżąco.

07

Podsumowanie

Operacja Java Kotlin
Odczytaj tekst et.getText().toString() et.text.toString()
Odczytaj i usuń spacje et.getText().toString().trim() et.text.toString().trim()
Sprawdź czy puste tekst.isEmpty() tekst.isEmpty()
Konwersja na int Integer.parseInt(tekst) tekst.toInt()
Konwersja na double Double.parseDouble(tekst) tekst.toDouble()
Ustaw tekst et.setText("tekst") et.setText("tekst")
Wyczyść pole et.getText().clear() et.text.clear()
Pokaż błąd et.setError("komunikat") et.setError("komunikat")
Usuń błąd et.setError(null) et.setError(null)
Dezaktywuj pole et.setEnabled(false) et.isEnabled = false
Nasłuch zmian tekstu et.addTextChangedListener(new TextWatcher() { ... }) et.addTextChangedListener(object : TextWatcher { ... })
Zadanie

Zadanie dla uczniów

Kalkulator BMI

  • Stwórz layout z dwoma polami EditText: wzrost w cm (inputType: number) i waga w kg (inputType: numberDecimal)
  • Dodaj przycisk „Oblicz BMI” i pole TextView na wynik
  • Zadeklaruj wszystkie widoki jako pola klasy, zainicjalizuj w initUI()
  • Przed obliczeniem sprawdź czy oba pola są wypełnione – użyj setError() na pustych polach
  • Oblicz BMI: waga / (wzrost_w_metrach * wzrost_w_metrach)
  • Wyświetl wynik w formacie: „BMI: 22.5 – prawidłowa masa ciała” (dodaj kategorię: <18.5 niedowaga, 18.5–24.9 norma, >24.9 nadwaga)

⭐ Bonus 1: zmień kolor tekstu wyniku w zależności od kategorii (zielony = norma, żółty = niedowaga, czerwony = nadwaga)

⭐⭐ Bonus 2: dodaj TextWatcher który aktywuje przycisk „Oblicz” dopiero gdy oba pola mają wartość (domyślnie przycisk setEnabled(false))

⭐⭐⭐ Bonus Kotlin: użyj ?.toDoubleOrNull() zamiast try-catch i obsłuż przypadek gdy konwersja nie powiedzie się