Demo App - Session 1 - Introduction to Android
Tutorial Demo: Membuat Aplikasi Android Pertama
Mata Kuliah: Mobile Technology Solution (COSC6103001) Sesi: 1 — Introduction to Android Bahasa: Kotlin Pendekatan UI: XML Layout + View Binding
Daftar Isi
- Tujuan Demo
- Persiapan
- Membuat Project Baru
- Memahami Struktur Project
- Menyiapkan Emulator (AVD)
- Mengaktifkan View Binding
- Menyiapkan Resource: Warna dan Teks
- Membangun Tampilan UI
- Menulis Logic di Kotlin
- Menjalankan dan Menguji Aplikasi
1. Tujuan Demo
Di akhir demo ini, aplikasi yang dibuat akan memiliki fitur:
- Kolom input untuk mengetik nama (dengan label mengambang khas Material Design)
- Tombol "Sapa Saya" yang menampilkan sapaan personal
- Tombol "Reset" yang mengembalikan tampilan ke kondisi awal
- Validasi input — menolak nama yang terlalu pendek dengan pesan error
- Penghitung (counter) berapa kali user sudah disapa
Konsep yang dipraktikkan:
| Konsep | Di mana muncul |
|---|---|
| Pemisahan XML (tampilan) dan Kotlin (logic) | Struktur file project |
| View Binding | MainActivity.kt |
| Lambda expression untuk click listener | setOnClickListener { } |
Percabangan if/else |
Validasi input nama |
| Variabel state di level class | Counter sapaan |
String template Kotlin ($variabel) |
Teks sapaan dinamis |
| String resource dengan parameter | strings.xml + getString() |
| Material Design Components | Layout XML |
2. Persiapan
Spesifikasi minimum komputer
| Komponen | Minimum | Direkomendasikan |
|---|---|---|
| OS (Windows) | Windows 10 64-bit | Windows 11 |
| OS (macOS) | macOS 12 (Monterey) | Versi terbaru |
| RAM | 8 GB (Studio saja) / 16 GB (Studio + Emulator) | 32 GB |
| Storage | 8 GB / 16 GB (dengan Emulator) | 20–40 GB (SSD) |
| CPU | Wajib dukungan virtualisasi (Intel VT-x / AMD-V aktif di BIOS) | Intel Gen-8 Core i5+ / AMD Ryzen / Apple Silicon |
Cek virtualisasi aktif (Windows)
Ini penyebab paling umum emulator gagal jalan meskipun laptop sudah kuat.
- Buka Task Manager (
Ctrl + Shift + Esc) - Buka tab Performance → klik CPU
- Cari baris Virtualization — harus tertulis Enabled
Kalau tertulis Disabled, perlu masuk BIOS (biasanya tekan F2 atau Del saat restart) dan aktifkan Intel Virtualization Technology (VT-x) atau AMD-V.
Download Android Studio
Unduh dari situs resmi: https://developer.android.com/studio
Halaman ini otomatis mendeteksi OS dan menawarkan installer yang sesuai. Saat first-time setup wizard muncul, pilih Standard (bukan Custom) agar Android SDK dan komponen emulator terunduh otomatis.
3. Membuat Project Baru
Langkah 3.1 — Buka New Project
Dari welcome screen, klik New Project. Kalau sudah ada project terbuka: File → New → New Project.
Langkah 3.2 — Pilih template yang TEPAT
PENTING: Di kategori Phone and Tablet, pilih "Empty Views Activity".
JANGAN pilih "Empty Activity" (tanpa kata Views) — itu template berbasis Jetpack Compose, yang tidak memakai XML sama sekali dan tidak cocok dengan tutorial ini.
Kalau kesulitan menemukannya, ketik views di kolom pencarian pada layar pemilihan template.
Cara memastikan pilihan sudah benar — setelah project jadi, buka MainActivity.kt:
| Ciri | Empty Views Activity (BENAR) | Empty Activity / Compose (SALAH) |
|---|---|---|
| Base class | AppCompatActivity() |
ComponentActivity() |
| Pemanggilan layout | setContentView(R.layout.activity_main) |
setContent { } |
| Ada file XML layout? | Ya, res/layout/activity_main.xml |
Tidak ada |
Langkah 3.3 — Isi konfigurasi project
| Field | Isi |
|---|---|
| Name | Hello Binus |
| Package name | biarkan default (com.example.hellobinus) |
| Save location | biarkan default |
| Language | Kotlin (pastikan bukan Java) |
| Minimum SDK | API 26 (Android 8.0 Oreo) |
| Build configuration language | Kotlin DSL (default) |
Klik Finish.
Penjelasan: apa itu Package Name?
Package name adalah identitas unik aplikasi, memakai format domain terbalik (reverse domain notation):
com.example.hellobinus
│ │ │
│ │ └── nama aplikasi
│ └── nama organisasi
└── domain tingkat atas (dibalik dari com)
Package name tidak boleh sama dengan aplikasi lain di Play Store — mirip seperti NIK yang unik untuk tiap orang. Prefix com.example.* adalah placeholder khusus untuk latihan/tutorial, tidak boleh dipakai untuk aplikasi yang benar-benar dipublikasikan.
Penjelasan: minSdk vs targetSdk
| Istilah | Arti | Analogi |
|---|---|---|
| minSdkVersion | Versi Android paling rendah yang boleh menginstall app | Batas umur minimum di bioskop |
| targetSdkVersion | Versi Android yang jadi acuan perilaku sistem terhadap app | "Saya mengikuti peraturan tahun sekian" |
| compileSdkVersion | API tertinggi yang boleh dipakai saat menulis kode | Edisi kamus yang dipakai saat menulis |
Menetapkan minSdk = 26 berarti app bisa diinstall di Android 8.0 ke atas — jangkauan luas tanpa terlalu banyak batasan fitur.
Catatan penting: Tidak ada "auto convert". Kalau kode memanggil API yang baru ada di versi Android lebih tinggi dari
minSdk, app akan crash di perangkat lama — kecuali dilindungi pengecekan versi (if (Build.VERSION.SDK_INT >= ...)) atau memakai library kompatibilitas AndroidX.
Langkah 3.4 — Tunggu Gradle sync
Android Studio akan mengunduh dependency dan menyiapkan project. Progress terlihat di status bar bawah: "Importing 'HelloBinus' Gradle Project".
Proses ini bisa memakan 1–5 menit pada percobaan pertama. Tunggu sampai selesai sebelum mengedit file apapun — kalau tidak, Android Studio bisa salah mendeteksi error yang sebenarnya tidak ada.
4. Memahami Struktur Project
Setelah sync selesai, panel kiri otomatis beralih ke mode Android view (bisa diganti lewat dropdown di pojok kiri atas panel).
app
├── manifests
│ └── AndroidManifest.xml → "KTP" aplikasi: daftar Activity, izin, ikon, tema
├── kotlin+java
│ ├── com.example.hellobinus → kode utama aplikasi
│ │ └── MainActivity.kt
│ ├── com.example.hellobinus (androidTest) → test yang dijalankan di emulator/device
│ └── com.example.hellobinus (test) → unit test yang dijalankan di komputer
├── res → semua resource (non-kode)
│ ├── drawable → gambar, ikon vektor
│ ├── layout → file XML tampilan
│ │ └── activity_main.xml
│ ├── mipmap → ikon launcher aplikasi
│ ├── values → colors.xml, strings.xml, themes.xml
│ └── xml → konfigurasi lain (backup rules, dll)
└── Gradle Scripts
├── build.gradle.kts (Project) → konfigurasi build level project
├── build.gradle.kts (Module :app) → konfigurasi build modul app ← SERING DIEDIT
├── gradle.properties
├── libs.versions.toml → katalog versi dependency
└── local.properties → path SDK di komputer lokal
Catatan menarik untuk dijelaskan ke mahasiswa
Folder source code tetap bernama java (atau kotlin+java di Android view) meskipun isinya file .kt. Ini warisan historis dari era Android yang awalnya 100% Java — konvensi nama foldernya tidak diubah meski bahasanya sudah bergeser ke Kotlin.
Isi awal MainActivity.kt (bawaan template)
package com.example.hellobinus
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
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
}
}
}
Penjelasan baris demi baris:
| Baris | Penjelasan |
|---|---|
class MainActivity : AppCompatActivity() |
Activity adalah satu "layar" aplikasi. AppCompatActivity adalah base class standar untuk pendekatan View/XML |
onCreate(...) |
Fungsi yang otomatis dipanggil sistem saat Activity pertama dibuat — ini bagian dari Activity Lifecycle (materi sesi 2) |
enableEdgeToEdge() |
Membuat app menggambar konten sampai ke belakang status bar dan navigation bar (tampilan modern, wajib sejak Android 15) |
setContentView(R.layout.activity_main) |
Menghubungkan Activity ini dengan file layout XML activity_main.xml |
ViewCompat.setOnApplyWindowInsetsListener(...) |
Pasangan dari enableEdgeToEdge() — memberi padding agar konten tidak tertutup status bar |
5. Menyiapkan Emulator (AVD)
Istilah: AVD vs Emulator
Dua istilah ini sering tertukar padahal berbeda level:
- AVD (Android Virtual Device) = konfigurasi/definisi perangkat virtual (model, versi Android, RAM, ukuran layar) — ibarat resep masakan
- Emulator = program yang menjalankan AVD tersebut — ibarat kompor yang memasak
Satu program Emulator bisa menjalankan banyak AVD berbeda.
Langkah 5.1 — Buka Device Manager
Ada dua cara:
- Klik ikon Device Manager di toolbar atas, atau
- Klik tab Device Manager di tab bar sisi kanan
Langkah 5.2 — Buat AVD baru
Klik tombol "+" → Create Virtual Device.
Catatan: Tampilan dialog ini berubah-ubah antar versi Android Studio. Pada versi lama terpisah menjadi 3 layar (Select Hardware → System Image → Verify Configuration), pada versi terbaru bisa digabung dalam satu layar. Konsepnya tetap sama.
Langkah 5.3 — Panduan memilih konfigurasi
a) Device profile
Pilih Medium Phone atau Pixel seri standar (bukan Pro/XL) — lebih representatif untuk mayoritas perangkat di pasar.
b) API Level
Pilih API level yang masih didukung (menerima security patch). Per September 2026:
| Versi Android | API Level | Status |
|---|---|---|
| Android 13 | 33 | ❌ EOL (Maret 2026) |
| Android 14 | 34 | ✅ Didukung |
| Android 15 | 35 | ✅ Didukung |
| Android 16 | 36 | ✅ Didukung |
| Android 17 | 37 | ✅ Didukung (terbaru) |
Rekomendasi: API 34 atau 35 — cukup baru untuk relevan, cukup matang untuk stabil.
Catatan istilah: EOL (End of Life) artinya Google berhenti merilis patch keamanan untuk versi OS tersebut. Ini tidak berarti developer dilarang membuat app untuk versi itu —
minSdkVersionboleh diset serendah apapun. Risikonya ditanggung pengguna perangkat lama, bukan developer.
c) ABI (arsitektur) — SANGAT PENTING
| Komputer host | ABI yang harus dipilih |
|---|---|
| Windows / Linux (Intel/AMD) | x86_64 |
| Mac Intel | x86_64 |
| Mac Apple Silicon (M1/M2/M3/M4) | arm64-v8a |
Salah memilih ABI di Mac M-series membuat emulator berjalan lewat emulasi berlapis — sangat lambat atau gagal jalan sama sekali. Image arm64 biasanya ada di tab "Other Images".
d) System Image type
Pilih varian "Google Play" (bukan hanya "Google APIs") — sudah termasuk Play Store, berguna untuk topik lanjutan seperti Push Notification yang bergantung pada Google Play Services.
e) Alokasi RAM
Klik Show Advanced Settings untuk mengatur RAM AVD. Sesuaikan dengan RAM laptop:
- Laptop 8 GB → alokasikan 1,5–2 GB untuk AVD
- Laptop 16 GB → alokasikan 2–4 GB untuk AVD
Langkah 5.4 — Jalankan emulator
Klik ikon play (▶) di samping AVD di Device Manager. Booting pertama kali biasanya paling lama (1–3 menit); berikutnya lebih cepat karena Android Studio menyimpan snapshot.
Tips untuk kelas besar
Tentukan satu konfigurasi AVD standar (nama, API level, device, RAM) dan minta semua mahasiswa memakai konfigurasi yang persis sama. Ini sangat memudahkan sesi troubleshooting bersama.
6. Mengaktifkan View Binding
Kenapa View Binding?
Sebelum masuk kode, penting memahami evolusi cara mengakses komponen UI dari Kotlin:
| Pendekatan | Status | Type-safe? |
|---|---|---|
findViewById manual |
Masih bisa, tapi kuno dan berulang | ❌ Tidak |
| Kotlin Synthetics | ❌ Dihapus Google tahun 2021 — jangan diajarkan | — |
| View Binding | ✅ Standar saat ini | ✅ Ya |
| Jetpack Compose | ✅ Paradigma baru (tanpa XML) | ✅ Ya |
Keunggulan View Binding dibanding findViewById:
- Type-safe — tidak perlu cast manual, IDE sudah tahu tipe setiap view
- Null-safe — view yang mungkin tidak ada ditandai nullable oleh compiler
- Error saat compile, bukan crash saat app dijalankan pengguna
- Tidak berulang — cukup satu kali setup, semua view bisa diakses
Langkah 6.1 — Edit build.gradle.kts (Module :app)
Buka Gradle Scripts → build.gradle.kts (Module :app).
Cari blok android { } yang sudah ada, lalu tambahkan buildFeatures di dalamnya:
android {
namespace = "com.example.hellobinus"
compileSdk = 35
defaultConfig {
applicationId = "com.example.hellobinus"
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "1.0"
}
// ... blok lain yang sudah ada (buildTypes, compileOptions, dst) ...
// TAMBAHKAN BLOK INI:
buildFeatures {
viewBinding = true
}
}
PERINGATAN: Jangan menghapus isi blok
android { }yang sudah ada. Cukup tambahkanbuildFeatures { }di dalamnya.
Langkah 6.2 — Sync project
Setelah menyimpan, akan muncul notifikasi bar bertuliskan "Gradle files have changed since last project sync" dengan tombol Sync Now. Klik tombol itu dan tunggu proses selesai.
7. Menyiapkan Resource: Warna dan Teks
Kenapa dipisah ke file resource?
Menaruh teks dan warna di file resource (bukan langsung di XML/Kotlin) adalah praktik standar Android karena:
- Mudah diterjemahkan — cukup buat
strings.xmlversi bahasa lain, tanpa menyentuh kode - Konsisten — satu warna dipakai di banyak tempat, mengubah satu titik mengubah semuanya
- Mudah dirawat — tidak perlu mencari teks yang tersebar di banyak file
Langkah 7.1 — Edit res/values/colors.xml
PERINGATAN KRITIS: Tambahkan baris di dalam tag
<resources>yang sudah ada. JANGAN menghapus warna bawaan template (biasanya bernamapurple_500,purple_700,teal_200,black,white, dsb) — warna-warna itu dipakai olehthemes.xml, dan menghapusnya menyebabkan error "Android resource linking failed".
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Warna bawaan template — JANGAN DIHAPUS -->
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<!-- Warna kustom untuk demo — TAMBAHKAN INI -->
<color name="brand_primary">#1565C0</color>
<color name="brand_background">#F5F7FA</color>
<color name="text_secondary">#757575</color>
</resources>
Langkah 7.2 — Edit res/values/strings.xml
PERINGATAN KRITIS: Pastikan
app_nametidak terhapus — string ini dipakaiAndroidManifest.xmluntukandroid:label. Menghapusnya menyebabkan build gagal.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- WAJIB ADA — jangan dihapus -->
<string name="app_name">Hello Binus</string>
<!-- String untuk demo -->
<string name="hint_name">Masukkan nama kamu</string>
<string name="btn_sapa">Sapa Saya</string>
<string name="btn_reset">Reset</string>
<string name="greeting_default">Halo! Siapa nama kamu?</string>
<string name="greeting_error">Nama minimal 2 huruf ya</string>
<string name="counter_zero">Belum pernah disapa</string>
<string name="counter_format">Sudah disapa %1$d kali</string>
</resources>
Penjelasan %1$d: ini placeholder untuk nilai dinamis bertipe angka (d = decimal/integer). Angka 1 berarti "parameter pertama". Nanti diisi dari Kotlin dengan getString(R.string.counter_format, greetCount).
8. Membangun Tampilan UI
Langkah 8.1 — Buka file layout
Buka res → layout → activity_main.xml, lalu klik tab "Code" di pojok kanan atas editor (bukan mode "Design" atau "Split").
Langkah 8.2 — Ganti seluruh isi file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:background="@color/brand_background"
android:padding="24dp">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
app:cardElevation="6dp"
app:cardBackgroundColor="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<!-- Teks sapaan utama -->
<TextView
android:id="@+id/textViewGreeting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/greeting_default"
android:textSize="22sp"
android:textStyle="bold"
android:textColor="@color/brand_primary"
android:gravity="center"
android:layout_marginBottom="4dp" />
<!-- Penghitung sapaan -->
<TextView
android:id="@+id/textViewCounter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/counter_zero"
android:textSize="13sp"
android:textColor="@color/text_secondary"
android:gravity="center"
android:layout_marginBottom="20dp" />
<!-- Input nama dengan label mengambang -->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textInputName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_name"
android:layout_marginBottom="16dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editTextName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName" />
</com.google.android.material.textfield.TextInputLayout>
<!-- Dua tombol berdampingan -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/buttonSapa"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="@string/btn_sapa" />
<com.google.android.material.button.MaterialButton
android:id="@+id/buttonReset"
style="?attr/materialButtonOutlinedStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_reset" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
Penjelasan atribut penting
| Atribut | Arti |
|---|---|
android:id="@+id/xxx" |
Memberi nama unik pada view. Tanda + berarti "buat id baru". Nama inilah yang nanti muncul di View Binding (binding.xxx) |
layout_width / layout_height |
match_parent = selebar induknya; wrap_content = secukupnya isi |
orientation="vertical" |
Pada LinearLayout: anak-anaknya disusun dari atas ke bawah |
gravity="center" |
Meratakan isi ke tengah |
padding |
Jarak dari tepi ke isi (di dalam) |
layout_margin |
Jarak dari tepi ke luar (memisahkan dari view lain) |
layout_weight="1" |
Membagi ruang secara proporsional. Dua tombol dengan weight 1 = masing-masing 50% lebar |
sp vs dp |
sp untuk ukuran teks (menyesuaikan preferensi font pengguna), dp untuk ukuran/jarak lainnya |
Kenapa LinearLayout, bukan ConstraintLayout?
Template Android Studio secara default memakai ConstraintLayout, yang jauh lebih fleksibel tapi butuh pemahaman sistem constraint (menghubungkan setiap sisi view ke view lain).
Untuk demo pertemuan pertama, LinearLayout lebih baik karena logikanya sederhana: isinya tersusun urut, atas ke bawah (atau kiri ke kanan). ConstraintLayout akan dibahas mendalam di Topik 4 (User Interface).
Catatan tentang android:id="@+id/main"
Id main pada root layout harus dipertahankan karena kode enableEdgeToEdge() bawaan template mereferensikannya. Kalau dihapus, akan terjadi error.
Komponen Material Design yang dipakai
| Komponen | Fungsi |
|---|---|
MaterialCardView |
Kartu dengan sudut membulat dan bayangan (elevation) |
TextInputLayout |
Wadah input dengan label mengambang — hint naik ke atas saat user mengetik |
TextInputEditText |
Kolom input teks yang dirancang untuk dipakai di dalam TextInputLayout |
MaterialButton |
Tombol dengan gaya Material Design |
style="?attr/materialButtonOutlinedStyle" |
Varian tombol outline (hanya garis tepi, tanpa isi warna) |
9. Menulis Logic di Kotlin
Langkah 9.1 — Ganti seluruh isi MainActivity.kt
package com.example.hellobinus
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.hellobinus.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
// View Binding: jembatan antara Kotlin dan komponen di XML
private lateinit var binding: ActivityMainBinding
// State: menyimpan berapa kali sudah disapa
private var greetCount = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
// Inflate layout lewat View Binding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Penanganan edge-to-edge (bawaan template)
ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
// Aksi tombol "Sapa Saya"
binding.buttonSapa.setOnClickListener {
val nama = binding.editTextName.text.toString().trim()
if (nama.length < 2) {
// Input tidak valid — tampilkan pesan error di kolom input
binding.textInputName.error = getString(R.string.greeting_error)
} else {
// Input valid — hapus error, tambah counter, perbarui tampilan
binding.textInputName.error = null
greetCount++
binding.textViewGreeting.text = "Halo, $nama! Selamat datang di Android."
binding.textViewCounter.text = getString(R.string.counter_format, greetCount)
}
}
// Aksi tombol "Reset"
binding.buttonReset.setOnClickListener {
binding.editTextName.text?.clear()
binding.textInputName.error = null
binding.textViewGreeting.text = getString(R.string.greeting_default)
binding.textViewCounter.text = getString(R.string.counter_zero)
greetCount = 0
}
}
}
Penting: Sesuaikan baris
package com.example.hellobinusdengan package name project kamu. Cek baris paling atas file yang sudah ada sebelum diganti.
Penjelasan konsep kunci
a) View Binding: dari XML ke Kotlin
private lateinit var binding: ActivityMainBinding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
Class ActivityMainBinding dibuat otomatis oleh Android Studio berdasarkan nama file layout:
activity_main.xml → ActivityMainBinding
Aturan penamaannya: snake_case di nama file menjadi PascalCase + akhiran Binding.
Begitu pula id di XML menjadi properti di Kotlin:
android:id="@+id/buttonSapa" → binding.buttonSapa
android:id="@+id/textViewGreeting" → binding.textViewGreeting
android:id="@+id/editTextName" → binding.editTextName
Kata kunci lateinit berarti: "variabel ini pasti akan diisi, tapi belum sekarang" — dipakai karena binding baru bisa dibuat di dalam onCreate(), bukan saat class dideklarasikan.
b) Lambda expression untuk click listener
binding.buttonSapa.setOnClickListener {
// kode yang dijalankan saat tombol diklik
}
Bandingkan dengan Java yang jauh lebih panjang untuk hal yang sama:
// Java — 6 baris
buttonSapa.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// kode
}
});
Kotlin membolehkan penulisan ringkas ini karena OnClickListener adalah SAM interface (Single Abstract Method — interface dengan tepat satu method). Compiler otomatis memahami bahwa isi kurung kurawal adalah isi method onClick().
Kalau butuh mengakses parameter view yang diklik:
binding.buttonSapa.setOnClickListener { view ->
view.visibility = View.GONE
}
// atau memakai kata kunci implisit "it":
binding.buttonSapa.setOnClickListener {
it.visibility = View.GONE
}
c) State di level class
class MainActivity : AppCompatActivity() {
private var greetCount = 0 // ← di sini, BUKAN di dalam listener
Ini titik yang sering salah dipahami pemula. Kalau greetCount dideklarasikan di dalam setOnClickListener, nilainya akan kembali ke 0 setiap klik karena variabelnya dibuat ulang. Dengan mendeklarasikannya di level class, nilainya bertahan selama Activity hidup.
Catatan untuk sesi berikutnya: nilai ini akan hilang kalau layar diputar (rotasi) — karena Activity dihancurkan dan dibuat ulang. Ini adalah pengantar sempurna ke materi Activity Lifecycle (Sesi 2).
d) Validasi input
val nama = binding.editTextName.text.toString().trim()
if (nama.length < 2) {
binding.textInputName.error = getString(R.string.greeting_error)
} else {
binding.textInputName.error = null
// ...
}
.textmengembalikan objekEditable, perlu.toString()untuk menjadiStringbiasa.trim()menghapus spasi di awal/akhir, agar" Budi "tetap dianggap validbinding.textInputName.error = "..."otomatis menampilkan pesan error merah di bawah kolom input — fitur bawaanTextInputLayout, tidak perlu membuat TextView error manualerror = nullmenghilangkan pesan error tersebut
e) String template
binding.textViewGreeting.text = "Halo, $nama! Selamat datang di Android."
Tanda $nama otomatis diganti dengan isi variabel — jauh lebih ringkas dibanding penggabungan string manual di Java ("Halo, " + nama + "! ...").
f) String resource dengan parameter
binding.textViewCounter.text = getString(R.string.counter_format, greetCount)
Mengambil string dari strings.xml ("Sudah disapa %1$d kali"), lalu mengisi placeholder %1$d dengan nilai greetCount. Pola ini sangat umum dipakai di project Android nyata karena mendukung terjemahan multi-bahasa.
10. Menjalankan dan Menguji Aplikasi
Langkah 10.1 — Jalankan
- Pastikan AVD yang benar terpilih di dropdown device (toolbar atas)
- Klik tombol Run (▶ hijau) atau tekan
Shift + F10 - Kalau app sudah pernah berjalan, tombolnya berubah jadi ikon refresh — klik untuk restart dengan kode terbaru
Langkah 10.2 — Uji tiga skenario
| # | Skenario | Hasil yang diharapkan |
|---|---|---|
| 1 | Ketik 1 huruf saja, klik "Sapa Saya" | Muncul pesan error merah "Nama minimal 2 huruf ya" di bawah kolom input |
| 2 | Ketik nama lengkap, klik "Sapa Saya" beberapa kali | Sapaan personal muncul; angka counter bertambah setiap klik |
| 3 | Klik "Reset" | Kolom input kosong, sapaan kembali ke default, counter kembali ke nol |