Membuat Aplikasi Android "Woof" dengan Jetpack Compose

Nama     : Iftala Zahri Sukmana
NRP       : 5025221002
Kelas      : G
Kode GitHub :  https://github.com/ifzahri/ppb/tree/main/woof

Dalam postingan blog ini, kita akan membedah file MainActivity.kt untuk memahami bagaimana setiap komponen berkontribusi pada keseluruhan aplikasi.

Struktur Dasar Aplikasi

Setiap aplikasi Compose dimulai dari sebuah Activity. Dalam kasus kita, MainActivity adalah titik masuknya. Di dalam metode onCreate, kita mengatur tampilan konten menggunakan setContent. Di sinilah keajaiban Compose dimulai.

Kotlin
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            WoofTheme { // 1. Menerapkan tema kustom aplikasi
                Surface( // 2. Container dasar untuk UI
                    modifier = Modifier.fillMaxSize()
                ) {
                    WoofApp() // 3. Composable utama aplikasi kita
                }
            }
        }
    }
}

Pertama, kita membungkus semuanya dengan WoofTheme. Ini memungkinkan kita untuk memiliki tema yang konsisten (seperti warna dan font) di seluruh aplikasi. Kemudian, Surface bertindak sebagai kanvas utama tempat elemen UI kita akan digambar. Di dalam Surface inilah WoofApp(), composable inti dari aplikasi kita, dipanggil.

WoofApp(): Kerangka Utama

WoofApp bertanggung jawab atas tata letak keseluruhan aplikasi. Ia menggunakan Scaffold, sebuah komponen Compose yang menyediakan struktur untuk UI Material Design yang umum.

Kotlin
@Composable
fun WoofApp() {
    Scaffold(
        topBar = { // Mendefinisikan AppBar bagian atas
            WoofTopAppBar()
        }
    ) { it -> // 'it' adalah contentPadding yang disediakan oleh Scaffold
        LazyColumn(contentPadding = it) { // Daftar yang dapat di-scroll
            items(dogs) { // Iterasi melalui daftar data anjing
                DogItem(
                    dog = it, // Meneruskan data anjing ke setiap item
                    modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
                )
            }
        }
    }
}

Scaffold di sini dikonfigurasi dengan topBar. WoofTopAppBar() adalah composable kustom yang akan kita bahas nanti. Konten utama dari Scaffold adalah LazyColumn. LazyColumn sangat efisien untuk menampilkan daftar yang panjang karena hanya me-render item yang terlihat di layar. Kita mengisi LazyColumn ini dengan DogItem, di mana setiap DogItem mewakili satu anjing dalam daftar. Modifier.padding digunakan untuk memberikan sedikit ruang di sekitar setiap DogItem.

WoofTopAppBar(): Judul Aplikasi yang Menarik

Setiap aplikasi yang baik membutuhkan AppBar yang jelas. WoofTopAppBar adalah composable yang menangani ini.

Kotlin
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
    CenterAlignedTopAppBar( // AppBar yang judulnya terpusat
        title = {
            Row( // Mengatur logo dan teks judul secara horizontal
                verticalAlignment = Alignment.CenterVertically
            ) {
                Image(
                    modifier = Modifier
                        .size(dimensionResource(R.dimen.image_size))
                        .padding(dimensionResource(R.dimen.padding_small)),
                    painter = painterResource(R.drawable.ic_woof_logo), // Logo aplikasi
                    contentDescription = null // Deskripsi konten null karena gambar ini dekoratif
                )
                Text(
                    text = stringResource(R.string.app_name), // Nama aplikasi
                    style = MaterialTheme.typography.displayLarge // Gaya teks dari tema
                )
            }
        },
        modifier = modifier
    )
}

Di sini, kita menggunakan CenterAlignedTopAppBar untuk memastikan judulnya berada di tengah. Judul itu sendiri adalah sebuah Row yang berisi Image (logo Woof) dan Text (nama aplikasi). Perhatikan bahwa contentDescription untuk Image diatur ke null. Ini adalah praktik yang baik untuk gambar dekoratif karena layanan aksesibilitas akan melewatkannya, sehingga tidak membingungkan pengguna yang mengandalkan layanan tersebut.

DogItem(): Menampilkan Setiap Anjing

Composable DogItem bertanggung jawab untuk menampilkan informasi setiap anjing dalam bentuk kartu.

Kotlin
@Composable
fun DogItem(
    dog: Dog, // Objek data anjing
    modifier: Modifier = Modifier
) {
    Card( // Menggunakan Card untuk tampilan yang rapi
        modifier = modifier
    ) {
        Row( // Mengatur ikon dan informasi anjing secara horizontal
            modifier = Modifier
                .fillMaxWidth() // Memenuhi lebar kartu
                .padding(dimensionResource(R.dimen.padding_small))
        ) {
            DogIcon(dog.imageResourceId) // Composable untuk ikon anjing
            DogInformation(dog.name, dog.age) // Composable untuk nama dan usia anjing
        }
    }
}

Setiap DogItem adalah sebuah Card yang berisi Row. Row ini menampung dua elemen utama: DogIcon (gambar anjing) dan DogInformation (nama dan usia anjing). Penggunaan Modifier.fillMaxWidth() memastikan Row mengisi seluruh lebar Card.

DogIcon() dan DogInformation(): Detail Lebih Lanjut

Mari kita lihat lebih dekat bagaimana ikon dan informasi anjing ditampilkan.

DogIcon():

Kotlin
@Composable
fun DogIcon(
    @DrawableRes dogIcon: Int, // ID resource gambar
    modifier: Modifier = Modifier
) {
    Image(
        modifier = modifier
            .size(dimensionResource(R.dimen.image_size)) // Mengatur ukuran gambar
            .padding(dimensionResource(R.dimen.padding_small)) // Memberi padding
            .clip(MaterialTheme.shapes.small), // Memberi sudut melengkung pada gambar
        contentScale = ContentScale.Crop, // Memotong gambar agar sesuai dengan ukuran
        painter = painterResource(dogIcon), // Sumber gambar
        contentDescription = null // Gambar dekoratif
    )
}

DogIcon adalah composable Image sederhana. Ia menggunakan painterResource untuk memuat gambar dari drawable resources. Modifier.clip(MaterialTheme.shapes.small) memberikan sentuhan bagus dengan membulatkan sudut-sudut gambar. ContentScale.Crop memastikan gambar mengisi ruang yang tersedia tanpa merusak rasio aspeknya. Sekali lagi, contentDescription adalah null karena gambar ini bersifat dekoratif dalam konteks item daftar.

DogInformation():

Kotlin
@Composable
fun DogInformation(
    @StringRes dogName: Int, // ID resource string untuk nama
    dogAge: Int, // Usia anjing
    modifier: Modifier = Modifier
) {
    Column(modifier = modifier) { // Mengatur nama dan usia secara vertikal
        Text(
            text = stringResource(dogName), // Menampilkan nama anjing
            style = MaterialTheme.typography.displayMedium, // Gaya teks dari tema
            modifier = Modifier.padding(top = dimensionResource(R.dimen.padding_small))
        )
        Text(
            text = stringResource(R.string.years_old, dogAge), // Menampilkan usia anjing
            style = MaterialTheme.typography.bodyLarge // Gaya teks dari tema
        )
    }
}

DogInformation menggunakan Column untuk menumpuk Text nama anjing di atas Text usianya. stringResource digunakan untuk memuat string nama dan format string usia dari resources, yang merupakan praktik terbaik untuk internasionalisasi. MaterialTheme.typography digunakan untuk menjaga konsistensi gaya teks.

Data Anjing dan Pratinjau

Aplikasi ini mendapatkan data anjingnya dari com.example.woof.data.Dog dan daftar com.example.woof.data.dogs. Meskipun definisi kelas Dog dan daftar dogs tidak ada dalam file ini, kita dapat berasumsi bahwa Dog adalah kelas data yang menyimpan imageResourceId, name (sebagai @StringRes), dan age (sebagai Int).

Terakhir, kode ini juga menyertakan fungsi pratinjau Composable: WoofPreview() dan WoofDarkThemePreview().

Kotlin
@Preview // Anotasi untuk pratinjau di Android Studio
@Composable
fun WoofPreview() {
    WoofTheme(darkTheme = false) { // Pratinjau dengan tema terang
        WoofApp()
    }
}

@Preview
@Composable
fun WoofDarkThemePreview() {
    WoofTheme(darkTheme = true) { // Pratinjau dengan tema gelap
        WoofApp()
    }
}

Anotasi @Preview memungkinkan pengembang untuk melihat bagaimana UI mereka akan terlihat langsung di dalam Android Studio tanpa perlu menjalankan aplikasi di emulator atau perangkat. Ini sangat berguna untuk iterasi cepat pada desain UI. Di sini, kita memiliki pratinjau untuk tema terang dan gelap.



Kesimpulan

Melalui analisis file MainActivity.kt ini, kita telah melihat bagaimana Jetpack Compose memungkinkan kita membangun antarmuka pengguna yang menarik dan terstruktur dengan cara yang deklaratif dan intuitif. Dari pengaturan tema dasar, pembuatan tata letak dengan Scaffold dan LazyColumn, hingga perancangan item individual dengan Card, Row, Column, Image, dan Text, setiap composable memainkan peran penting dalam menciptakan aplikasi Woof.



Komentar

Postingan populer dari blog ini

Aplikasi Starbucks Clone dengan Android Studio

Membuat Login Form Elegan dengan Jetpack Compose di Android Studio

Tutorial Pembuatan Aplikasi Dice Roller Interaktif dengan Jetpack Compose