school-it.pl // android + kotlin // rozdział 1 // lekcja 01
Android Studio i pierwsza aplikacja
Aplikacja na telefon składa się z dwóch części: wyglądu zapisanego w pliku XML i kodu w Kotlinie, który ten wygląd ożywia. W tej lekcji utworzysz pierwszy projekt w Android Studio, poznasz pliki, z których się składa, uruchomisz go na wirtualnym telefonie i zbudujesz własną wizytówkę — ekran z twoimi danymi.
Czego się dziś nauczysz
- Utworzysz projekt Empty Views Activity w Android Studio.
- Wskażesz pliki odpowiedzialne za wygląd, kod i ustawienia aplikacji.
- Uruchomisz aplikację na emulatorze.
- Zbudujesz ekran z kilku napisów w pliku XML.
- Zmienisz napis z kodu Kotlin za pomocą
findViewById.
Narzędzia
Do pisania aplikacji na Androida potrzebujesz jednego programu — Android Studio. Instalator dociąga resztę. Warto jednak wiedzieć, co jest czym, bo komunikaty o błędach używają tych nazw:
| Nazwa | Do czego służy | Kiedy o niej usłyszysz |
|---|---|---|
| Android Studio | Edytor kodu i wyglądu, uruchamianie, wyszukiwanie błędów. | Cały czas — to twoje środowisko pracy. |
| Android SDK | Biblioteki Androida i narzędzia do budowania aplikacji. | „SDK platform not installed” — brakuje wersji Androida. |
| Gradle | Program, który buduje aplikację z twoich plików. | „Gradle sync failed”, przycisk Sync Now. |
| Emulator | Wirtualny telefon na komputerze. | Okno Device Manager, wybór urządzenia przed uruchomieniem. |
Podgląd to jeszcze nie aplikacja
Android Studio pokazuje podgląd ekranu już podczas pisania XML. To tylko rysunek. Aplikacja działa naprawdę dopiero na emulatorze albo telefonie — tam też wykonuje się kod Kotlin.
Nowy projekt
W Android Studio: File → New → New Project… (na ekranie powitalnym: New Project). Kreator ma dwa kroki.
Krok 1 — szablon. W kategorii Phone and Tablet wybierz Empty Views Activity. Uważaj na podobnie nazwany Empty Activity: ten używa Jetpack Compose, czyli zupełnie innego sposobu budowania ekranu, i nie ma plików XML z wyglądem.
Krok 2 — ustawienia:
| Pole | Wpisz | Znaczenie |
|---|---|---|
| Name | Wizytowka | Nazwa aplikacji i folderu projektu. Bez polskich znaków i spacji. |
| Package name | pl.schoolit.wizytowka | Unikalny identyfikator aplikacji — odwrócony adres strony + nazwa. |
| Save location | twój folder | Miejsce na dysku. Unikaj ścieżek z polskimi znakami. |
| Language | Kotlin | Język kodu. |
| Minimum SDK | API 24 | Najstarszy Android, na którym aplikacja się uruchomi (Android 7.0). |
| Build configuration language | Kotlin DSL | Język plików Gradle — zostaw domyślny. |
Po Finish Android Studio pobiera potrzebne pliki i synchronizuje projekt. Przy pierwszym projekcie trwa to kilka minut — postęp widać na dolnym pasku. Nie zmieniaj niczego, dopóki synchronizacja się nie skończy.
Pliki projektu
Po lewej stronie jest panel Project. Ustaw nad nim widok Android — pokazuje tylko pliki, które edytujesz. Najważniejsze są cztery:
├── manifests/
│ └── AndroidManifest.xmlspis ekranów i ustawień aplikacji
├── kotlin+java/
│ └── pl.schoolit.wizytowka/
│ └── MainActivity.ktkod ekranu
└── res/zasoby (resources)
├── layout/
│ └── activity_main.xmlwygląd ekranu
└── values/
└── strings.xmlteksty (lekcja 02)
| Plik | Za co odpowiada |
|---|---|
activity_main.xml | Wygląd: jakie kontrolki są na ekranie, jakie mają rozmiary, kolory i teksty. To opis, a nie polecenia wykonywane po kolei. |
MainActivity.kt | Zachowanie: co się dzieje po uruchomieniu ekranu i po kliknięciach. |
AndroidManifest.xml | Spis ekranów aplikacji, nazwa, ikona, uprawnienia. Tu jest zapisane, który ekran otwiera się po kliknięciu ikony. |
build.gradle.kts (Module :app) | Ustawienia budowania: minimalne API, dodatkowe biblioteki. |
Ekran aplikacji to w Androidzie aktywność (Activity). Jedna aktywność = jeden plik Kotlin + jeden plik XML. Aplikacja z trzema ekranami ma trzy aktywności — tym zajmiemy się w rozdziale 8.
Trzy widoki pliku XML
Nad otwartym plikiem activity_main.xml po prawej są przyciski Code, Split i Design. W kursie pracujemy w trybie Split: po lewej piszesz XML, po prawej od razu widzisz podgląd.
Jak startuje aplikacja
Gdy dotkniesz ikony aplikacji, Android sprawdza w manifeście, który ekran jest startowy, tworzy tę aktywność i wywołuje jej metodę onCreate. To w niej ekran dostaje swój wygląd:
uruchamia aplikację
MainActivity
R.layout.activity_main)
widać na telefonie
setContentView(R.layout.activity_main) czyta plik activity_main.xml, tworzy z niego kontrolki i pokazuje je. R to klasa, którą Android Studio generuje samo — zawiera numer każdego zasobu: R.layout.activity_main to plik wyglądu, R.id.tvPowitanie to kontrolka o identyfikatorze tvPowitanie.
Gdy kod ma coś zmienić na ekranie, najpierw musi znaleźć kontrolkę. Służy do tego findViewById — „znajdź widok po identyfikatorze”:
setContentView(R.layout.activity_main) // 1. zbuduj ekran z XML
val tvPowitanie = findViewById<TextView>(R.id.tvPowitanie) // 2. znajdź napis
tvPowitanie.text = "Cześć!" // 3. zmień jego tekst
W nawiasach ostrych <TextView> mówisz, jakiego rodzaju kontrolki szukasz — wtedy Kotlin wie, że ma ona właściwość text. Kolejność jest ważna: kontrolki istnieją dopiero po setContentView.
Szablon i nasze uproszczenie
Nowy projekt zawiera taki plik MainActivity.kt:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}
Nowe Androidy rysują aplikację na całym ekranie — także pod paskiem stanu (godzina, bateria) i pod paskiem nawigacji. Linie z enableEdgeToEdge i ViewCompat odsuwają treść od tych pasków, żeby nic się pod nimi nie schowało.
W kursie zamiast tych linii używamy jednego atrybutu w XML — android:fitsSystemWindows="true" w głównym układzie. Efekt jest ten sam, a w onCreate zostaje tylko to, co ważne:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
napis wchodzi pod pasek stanu
treść zaczyna się pod paskiem
atrybut odsuwa treść od pasków systemu — tak samo jak kod z szablonu
fitsSystemWindows zajmuje padding
Ten atrybut działa w ten sposób, że ustawia układowi padding równy wysokości pasków. Jeśli w tym samym elemencie wpiszesz android:padding="16dp", twój padding zostanie zastąpiony. Dlatego odstęp od krawędzi ekranu w głównym układzie dajemy przez android:layout_margin="16dp".
Emulator i uruchamianie
- Otwórz Device Manager (ikona telefonu na prawym pasku albo Tools → Device Manager).
- Jeśli lista jest pusta: + → Create Virtual Device → wybierz telefon (np. Pixel) → obraz systemu z najnowszym stabilnym API (pobierz go strzałką) → Finish.
- Na górnym pasku Android Studio wybierz to urządzenie z listy i kliknij zielony trójkąt Run 'app’ (Shift+F10).
- Pierwsze uruchomienie emulatora trwa dłużej. Nie zamykaj go między kolejnymi uruchomieniami — następne będą szybkie.
Zamiast emulatora możesz użyć własnego telefonu: w ustawieniach telefonu włącz Opcje programisty (siedem dotknięć „Numer kompilacji” w Informacjach o telefonie), w nich Debugowanie USB, podłącz kabel i zaakceptuj komunikat na telefonie.
| Okno na dole ekranu | Co w nim znajdziesz |
|---|---|
| Build | Błędy kompilacji — kod jest źle napisany i aplikacja w ogóle się nie uruchomi. Kliknięcie błędu przenosi do linii. |
| Logcat | Komunikaty z działającej aplikacji. Gdy aplikacja się zamyka, szukaj tu czerwonego wpisu FATAL EXCEPTION — kilka linii niżej jest nazwa twojego pliku i numer linii. |
Wizytówka ucznia
Ekran z danymi ucznia: imię i nazwisko, klasa, szkoła i zainteresowania. Wszystko to opisuje XML. Najwyższy napis jest w XML pusty — wpisuje go kod Kotlin w onCreate, żeby było widać, że kod naprawdę działa.
pierwsza linia pochodzi z kodu Kotlin, reszta — z pliku XML
Przygotowanie projektu
- Utwórz projekt Empty Views Activity z ustawieniami z tabeli wyżej i poczekaj na koniec synchronizacji.
- Uruchom projekt bez żadnych zmian. Na ekranie zobaczysz „Hello World!”. Jeśli to działa, środowisko jest gotowe — ewentualne późniejsze błędy będą w twoim kodzie, a nie w instalacji.
- Podmień całą zawartość
activity_main.xmliMainActivity.ktna kod poniżej. Pierwszą liniępackage …zostaw taką, jaką utworzył twój projekt.
<?xml version="1.0" encoding="utf-8"?>
<!-- LinearLayout układa kontrolki jedna pod drugą (szczegóły w lekcji 02) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="16dp"
android:fitsSystemWindows="true">
<!-- pusty napis — tekst wpisze kod Kotlin -->
<TextView
android:id="@+id/tvPowitanie"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="italic"
android:textColor="#6750A4" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Jan Kowalski"
android:textSize="28sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Klasa 3TP · technik programista"
android:textSize="18sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Szkoła: ZSMI w Lęborku"
android:textSize="18sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Zainteresowania"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="gry komputerowe, robotyka, rower"
android:textSize="16sp" />
</LinearLayout>
package pl.schoolit.wizytowka
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// znajdujemy napis po identyfikatorze i wpisujemy do niego tekst
val tvPowitanie = findViewById<TextView>(R.id.tvPowitanie)
tvPowitanie.text = "Cześć! To moja pierwsza aplikacja."
}
}
Co dzieje się po kolei
- Plik XML ma jeden główny element
LinearLayout, a w nim sześć napisówTextView. Pojawią się na ekranie jeden pod drugim, w kolejności z pliku. - Pierwszy napis ma identyfikator
android:id="@+id/tvPowitanie". Znak+oznacza „utwórz nowy identyfikator”. Pozostałe napisy nie mająid— kod ich nie zmienia, więc go nie potrzebują. layout_widthilayout_heightmusi mieć każda kontrolka:match_parentto „na całą dostępną szerokość”,wrap_content— „tyle, ile potrzebuje treść”.- Rozmiar tekstu podajemy w
sp, a odstępy wdp. Obie jednostki dopasowują się do gęstości ekranu, więc napis ma podobną wielkość na każdym telefonie. - W
onCreatenajpierwsetContentViewbuduje ekran, potemfindViewByIdznajduje pusty napis, a przypisanie dotextzmienia jego treść. - Linie
import …na górze mówią Kotlinowi, gdzie są używane klasy. Gdy wpiszesz nową klasę i podświetli się na czerwono, kliknij ją i naciśnij Alt+Enter → Import.
Sprawdź trzy rzeczy
- Przełącz plik XML w tryb Split. Pierwszy napis w podglądzie jest pusty, a na emulatorze — wypełniony. Podgląd nie wykonuje kodu Kotlin.
- Przenieś dwie linie z
findViewByIdnadsetContentView. Aplikacja zamknie się zaraz po starcie. Otwórz Logcat i znajdź FATAL EXCEPTION. Przywróć kolejność. - Obróć emulator (przyciski obrotu na jego pasku bocznym). Ekran ułoży się poziomo, a tekst z kodu nadal będzie widoczny —
onCreatewykonało się ponownie.
Zestawienie elementów
| Element | Typ | Co robi |
|---|---|---|
AppCompatActivity | klasa | Klasa bazowa ekranu; MainActivity po niej dziedziczy. |
onCreate(savedInstanceState) | metoda | Wywoływana przez Androida przy tworzeniu ekranu. |
super.onCreate(…) | wywołanie | Najpierw robi swoją pracę klasa bazowa. Musi być pierwszą linią. |
setContentView(R.layout.…) | metoda | Buduje ekran z pliku XML. |
findViewById<Typ>(R.id.…) | metoda | Znajduje kontrolkę po identyfikatorze. |
R | klasa generowana | Numery zasobów: R.layout, R.id, R.string… |
<TextView> / .text | kontrolka | Napis; właściwość text odczytuje i zmienia treść. |
android:id="@+id/nazwa" | atrybut | Nadaje kontrolce identyfikator. |
match_parent / wrap_content | wartość | Rozmiar: jak rodzic / jak treść. |
dp, sp | jednostki | Odstępy i rozmiary / rozmiar tekstu. |
android:fitsSystemWindows="true" | atrybut | Odsuwa treść od paska stanu i nawigacji. |
Zanim utkniesz
| Objaw | Przyczyna i poprawka |
|---|---|
W projekcie jest setContent { … } i brak folderu layout | Wybrano szablon Empty Activity (Compose). Utwórz projekt jeszcze raz z Empty Views Activity. |
| Unresolved reference: tvPowitanie | Brak android:id="@+id/tvPowitanie" w XML albo literówka w nazwie. Wielkość liter ma znaczenie. |
| Aplikacja zamyka się zaraz po starcie | findViewById przed setContentView, albo id z innego pliku XML. Szczegóły w Logcat. |
| Unresolved reference: R | Błąd w którymś pliku XML — Android Studio nie wygenerował klasy R. Najpierw popraw błędy XML (okno Build). |
| Przycisk Run jest szary | Trwa synchronizacja Gradle albo nie wybrano urządzenia. |
| Treść pod paskiem stanu | Brak android:fitsSystemWindows="true" w głównym układzie. |
Zmieniona linia package na górze MainActivity.kt | Klasa trafia do innego pakietu niż w projekcie — pojawia się Unresolved reference: R albo aplikacja nie startuje. Linia package ma zostać z twojego projektu. |
Zadania
Zadania 1–3 wykonaj w projekcie z lekcji, zadania 4–6 w nowych projektach Empty Views Activity. Wskazówkę otwórz dopiero wtedy, gdy utkniesz.
Wpisz do wizytówki swoje dane. Dodaj dwa napisy: „Ulubiony przedmiot: …” i „Kim chcę zostać: …”. Uruchom aplikację i pokaż ją nauczycielowi na emulatorze.
pokaż wskazówkę
- Skopiuj cały blok
<TextView … />i zmień tylkoandroid:text.
Imię i nazwisko ma być w kolorze ciemnoniebieskim (#0D47A1) i rozmiarze 32sp, a napis „Zainteresowania” — wyśrodkowany. Dodaj nad imieniem odstęp 32dp.
pokaż wskazówkę
- Kolor tekstu:
android:textColor, wyśrodkowanie tekstu w napisie:android:gravity="center", odstęp nad kontrolką:android:layout_marginTop.
Dodaj na dole wizytówki pusty napis z identyfikatorem tvStopka. W onCreate wpisz do niego „Wizytówka wykonana w Android Studio”. Zmień też z kodu tekst imienia i nazwiska — będzie potrzebne mu id.
pokaż wskazówkę
- Każda kontrolka, którą zmieniasz z kodu, potrzebuje własnego
idi własnegofindViewById.
Nowy projekt PlanDnia. Tytuł „Poniedziałek” i osiem napisów z lekcjami: „1. 8:00 — Matematyka” itd. Lekcje informatyczne mają zielony kolor tekstu. Pod listą lekcji napis z kodu: „Lekcji: 8”.
pokaż wskazówkę
- Jeśli lekcje nie zmieszczą się na ekranie — to dobry moment, żeby zauważyć, że
LinearLayoutsam nie przewija. Przewijanie poznasz w lekcji 03.
Nowy projekt: ekran wymyślonego sklepu. Nazwa sklepu wyśrodkowana, duża, pogrubiona. Pod nią godziny otwarcia na każdy dzień tygodnia, adres i telefon. Tło głównego układu ma kolor #FFF8E1. Z kodu ustaw napis „Dziś otwarte do 18:00”.
pokaż wskazówkę
- Tło:
android:background="#FFF8E1"wLinearLayout. Tekst wyśrodkowany w całej szerokości:match_parent+android:gravity="center".
W kopii projektu z lekcji wprowadź po kolei pięć błędów (za każdym razem tylko jeden): literówka w R.id; usunięty > zamykający znacznik w XML; findViewById przed setContentView; findViewById<TextView> z identyfikatorem nieistniejącym w tym XML, ale istniejącym w innym pliku układu; usunięty import android.widget.TextView. Dla każdego zapisz w tabeli: czy aplikacja się zbudowała, w którym oknie (Build czy Logcat) był komunikat i jak brzmiała jego najważniejsza linia.
pokaż wskazówkę
- Błędy kompilacji zatrzymują budowanie (okno Build). Błędy działania pozwalają zbudować aplikację, ale zamykają ją na telefonie (okno Logcat, filtr: nazwa twojego pakietu). Drugi plik układu utworzysz przez prawy przycisk na
res/layout→ New → Layout Resource File.
Co trzeba zapamiętać
- Nowy projekt w kursie to zawsze Empty Views Activity, język Kotlin, minimalne API 24.
- Wygląd jest w
res/layout/activity_main.xml, zachowanie wMainActivity.kt, spis ekranów wAndroidManifest.xml. onCreateuruchamia się przy tworzeniu ekranu;setContentViewbuduje ekran z XML.- Kontrolkę zmienianą z kodu oznacz
android:id="@+id/…"i znajdź przezfindViewById— zawsze posetContentView. - Błędy pisowni pokazuje okno Build, awarie działającej aplikacji — Logcat.
Dokumentacja: Tworzenie projektu, Emulator i urządzenia wirtualne, Aktywności.