TeachingMobile Technology SolutionDemo App - Session 1 - Introduction to Android
Week 1Workshop

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

  1. Tujuan Demo
  2. Persiapan
  3. Membuat Project Baru
  4. Memahami Struktur Project
  5. Menyiapkan Emulator (AVD)
  6. Mengaktifkan View Binding
  7. Menyiapkan Resource: Warna dan Teks
  8. Membangun Tampilan UI
  9. Menulis Logic di Kotlin
  10. 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.

  1. Buka Task Manager (Ctrl + Shift + Esc)
  2. Buka tab Performance → klik CPU
  3. 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 — minSdkVersion boleh 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 tambahkan buildFeatures { } 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.xml versi 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 bernama purple_500, purple_700, teal_200, black, white, dsb) — warna-warna itu dipakai oleh themes.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_name tidak terhapus — string ini dipakai AndroidManifest.xml untuk android: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.hellobinus dengan 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
    // ...
}
  • .text mengembalikan objek Editable, perlu .toString() untuk menjadi String biasa
  • .trim() menghapus spasi di awal/akhir, agar " Budi " tetap dianggap valid
  • binding.textInputName.error = "..." otomatis menampilkan pesan error merah di bawah kolom input — fitur bawaan TextInputLayout, tidak perlu membuat TextView error manual
  • error = null menghilangkan 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

  1. Pastikan AVD yang benar terpilih di dropdown device (toolbar atas)
  2. Klik tombol Run (▶ hijau) atau tekan Shift + F10
  3. 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