Tugas 9 PPB

 

TUGAS 9 PPB

MATERIAL THEMING - WOOF APPLICATION




Nama: Muhammad Lintang Panjerino

NRP: 5025201045

Kelas: PPB I

Tahun: 2024

Link Github: Tugas 9 - Material Theming Woof Application


Pada Tugas 9 PPB kali ini, diberikan tugas untuk membuat proyek Material Theming - Woof Application dengan menggunakan Jetpack Compose pada Android Studio. Secara garis besar, aplikasi Material Theming - Woof Application ini adalah sebuah aplikasi yang memuat daftar beberapa card yang berisi foto, nama, dan gambar hewan peliharaan, yaitu anjing. Daftar anjing tersebut dapat di-scroll dan karena merupakan daftar anjing, aplikasi ini diberi nama Woof. Proyek ini bertujuan untuk mempelajari lebih dalam tentang konsep Card, Lazy Column, List, Color, Shape, Typography, dan Top Bar pada Jetpack Compose.

Untuk memulai pengerjaan proyek, langkah awal yang dilakukan adalah mengunduh file zip dari repository github berikut https://github.com/google-developer-training/basic-android-kotlin-compose-training-woof dan pilih branch dengan nama "starter". Kemudian ekstrak file zip tersebut pada folder lokal PC/laptop dan ubah nama folder hasil ekstrak menjadi "Woof Application". Pada Android Studio, pilih "File" > pilih "Open" > pilih file tempat folder projek diekstrak > pilih "OK".


Setelah folder proyek terbuka, masih ada proses gradle build. Proses ini akan memakan waktu beberapa menit. Berikut adalah tampilan awal pada file MainActivity.kt. File ini merupakan file utama yang akan digunakan sebagai tempat untuk fungsi pembuatan card, pembuatan foto anjing, pembuatan nama dan umur anjing, dan pembuatan panel atas aplikasi.


Setelah aplikasi dijalankan melalui emulator dengan perintah "Run app", berikut adalah tampilan awal  atau starter dari aplikasi Woof.


Berikut merupakan penjelasan tentang kode starter dari Woof Application:
1. Buka kode starter di Android Studio.
2. Buka com.example.woof > data > Dog.kt. File ini berisi Dog data class yang akan digunakan untuk mewakili foto, nama, dan usia anjing. File ini juga berisi daftar anjing dan informasi sebagai data di Woof Application.
3. Buka res > drawable. File ini berisi semua aset gambar (ikon aplikasi, gambar anjing, dan ikon anjing) yang dibutuhkan untuk proyek Woof Application.
4. Buka res > values > strings.xml. File ini berisi string (nama aplikasi, nama anjing, dan deskripsi) yang dibutuhkan untuk proyek Woof Application.
5. Buka MainActivity.kt. File ini berisi kode untuk membuat daftar sederhana yang menampilkan foto anjing, nama anjing, dan usia anjing tersebut.
6. WoofApp() berisi LazyColumn yang menampilkan DogItem.
7. DogItem() berisi Row yang menampilkan foto anjing dan informasinya.
8. DogIcon() menampilkan foto anjing.
9. DogInformation() menampilkan nama dan usia anjing.
10. WoofPreview() memungkinkan Anda melihat pratinjau aplikasi di panel Design.

Secara garis besar, proyek Woof Application terbagi menjadi 4 bagian, yaitu menambahkan warna tema, menambahkan bentuk card, menambahkan tipografi, dan menambahkan panel atas aplikasi.

1. Menambahkan Warna

Hal pertama yang harus dilakukan adalah mengubah skema warna pada Woof Application. Skema warna adalah kombinasi warna yang digunakan oleh aplikasi. Kombinasi warna yang berbeda pada suatu aplikasi akan membangkitkan suasana hati yang berbeda dan memengaruhi perasaan orang saat menggunakan aplikasi. Berikut adalah langkah-langkah pada bagian menambahkan warna

Menambahkan palet warna ke tema

a. Buka file Color.kt dan ubah isi file dengan kode di bawah ini untuk skema warna aplikasi.

package com.example.woof.ui.theme

import androidx.compose.ui.graphics.Color

val md_theme_light_primary = Color(0xFF006C4C)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_primaryContainer = Color(0xFF89F8C7)
val md_theme_light_onPrimaryContainer = Color(0xFF002114)
val md_theme_light_secondary = Color(0xFF4D6357)
val md_theme_light_onSecondary = Color(0xFFFFFFFF)
val md_theme_light_secondaryContainer = Color(0xFFCFE9D9)
val md_theme_light_onSecondaryContainer = Color(0xFF092016)
val md_theme_light_tertiary = Color(0xFF3D6373)
val md_theme_light_onTertiary = Color(0xFFFFFFFF)
val md_theme_light_tertiaryContainer = Color(0xFFC1E8FB)
val md_theme_light_onTertiaryContainer = Color(0xFF001F29)
val md_theme_light_error = Color(0xFFBA1A1A)
val md_theme_light_errorContainer = Color(0xFFFFDAD6)
val md_theme_light_onError = Color(0xFFFFFFFF)
val md_theme_light_onErrorContainer = Color(0xFF410002)
val md_theme_light_background = Color(0xFFFBFDF9)
val md_theme_light_onBackground = Color(0xFF191C1A)
val md_theme_light_surface = Color(0xFFFBFDF9)
val md_theme_light_onSurface = Color(0xFF191C1A)
val md_theme_light_surfaceVariant = Color(0xFFDBE5DD)
val md_theme_light_onSurfaceVariant = Color(0xFF404943)
val md_theme_light_outline = Color(0xFF707973)
val md_theme_light_inverseOnSurface = Color(0xFFEFF1ED)
val md_theme_light_inverseSurface = Color(0xFF2E312F)
val md_theme_light_inversePrimary = Color(0xFF6CDBAC)
val md_theme_light_shadow = Color(0xFF000000)
val md_theme_light_surfaceTint = Color(0xFF006C4C)
val md_theme_light_outlineVariant = Color(0xFFBFC9C2)
val md_theme_light_scrim = Color(0xFF000000)

val md_theme_dark_primary = Color(0xFF6CDBAC)
val md_theme_dark_onPrimary = Color(0xFF003826)
val md_theme_dark_primaryContainer = Color(0xFF005138)
val md_theme_dark_onPrimaryContainer = Color(0xFF89F8C7)
val md_theme_dark_secondary = Color(0xFFB3CCBE)
val md_theme_dark_onSecondary = Color(0xFF1F352A)
val md_theme_dark_secondaryContainer = Color(0xFF354B40)
val md_theme_dark_onSecondaryContainer = Color(0xFFCFE9D9)
val md_theme_dark_tertiary = Color(0xFFA5CCDF)
val md_theme_dark_onTertiary = Color(0xFF073543)
val md_theme_dark_tertiaryContainer = Color(0xFF244C5B)
val md_theme_dark_onTertiaryContainer = Color(0xFFC1E8FB)
val md_theme_dark_error = Color(0xFFFFB4AB)
val md_theme_dark_errorContainer = Color(0xFF93000A)
val md_theme_dark_onError = Color(0xFF690005)
val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
val md_theme_dark_background = Color(0xFF191C1A)
val md_theme_dark_onBackground = Color(0xFFE1E3DF)
val md_theme_dark_surface = Color(0xFF191C1A)
val md_theme_dark_onSurface = Color(0xFFE1E3DF)
val md_theme_dark_surfaceVariant = Color(0xFF404943)
val md_theme_dark_onSurfaceVariant = Color(0xFFBFC9C2)
val md_theme_dark_outline = Color(0xFF8A938C)
val md_theme_dark_inverseOnSurface = Color(0xFF191C1A)
val md_theme_dark_inverseSurface = Color(0xFFE1E3DF)
val md_theme_dark_inversePrimary = Color(0xFF006C4C)
val md_theme_dark_shadow = Color(0xFF000000)
val md_theme_dark_surfaceTint = Color(0xFF6CDBAC)
val md_theme_dark_outlineVariant = Color(0xFF404943)
val md_theme_dark_scrim = Color(0xFF000000)

b. Buka file Theme.kt dan ubah isi file dengan kode di bawah ini untuk menambahkan warna baru ke tema.

package com.example.woof.ui.theme

import android.app.Activity
import android.os.Build
import android.view.View
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat

private val LightColors = lightColorScheme(
    primary = md_theme_light_primary,
    onPrimary = md_theme_light_onPrimary,
    primaryContainer = md_theme_light_primaryContainer,
    onPrimaryContainer = md_theme_light_onPrimaryContainer,
    secondary = md_theme_light_secondary,
    onSecondary = md_theme_light_onSecondary,
    secondaryContainer = md_theme_light_secondaryContainer,
    onSecondaryContainer = md_theme_light_onSecondaryContainer,
    tertiary = md_theme_light_tertiary,
    onTertiary = md_theme_light_onTertiary,
    tertiaryContainer = md_theme_light_tertiaryContainer,
    onTertiaryContainer = md_theme_light_onTertiaryContainer,
    error = md_theme_light_error,
    errorContainer = md_theme_light_errorContainer,
    onError = md_theme_light_onError,
    onErrorContainer = md_theme_light_onErrorContainer,
    background = md_theme_light_background,
    onBackground = md_theme_light_onBackground,
    surface = md_theme_light_surface,
    onSurface = md_theme_light_onSurface,
    surfaceVariant = md_theme_light_surfaceVariant,
    onSurfaceVariant = md_theme_light_onSurfaceVariant,
    outline = md_theme_light_outline,
    inverseOnSurface = md_theme_light_inverseOnSurface,
    inverseSurface = md_theme_light_inverseSurface,
    inversePrimary = md_theme_light_inversePrimary,
    surfaceTint = md_theme_light_surfaceTint,
    outlineVariant = md_theme_light_outlineVariant,
    scrim = md_theme_light_scrim,
)

private val DarkColors = darkColorScheme(
    primary = md_theme_dark_primary,
    onPrimary = md_theme_dark_onPrimary,
    primaryContainer = md_theme_dark_primaryContainer,
    onPrimaryContainer = md_theme_dark_onPrimaryContainer,
    secondary = md_theme_dark_secondary,
    onSecondary = md_theme_dark_onSecondary,
    secondaryContainer = md_theme_dark_secondaryContainer,
    onSecondaryContainer = md_theme_dark_onSecondaryContainer,
    tertiary = md_theme_dark_tertiary,
    onTertiary = md_theme_dark_onTertiary,
    tertiaryContainer = md_theme_dark_tertiaryContainer,
    onTertiaryContainer = md_theme_dark_onTertiaryContainer,
    error = md_theme_dark_error,
    errorContainer = md_theme_dark_errorContainer,
    onError = md_theme_dark_onError,
    onErrorContainer = md_theme_dark_onErrorContainer,
    background = md_theme_dark_background,
    onBackground = md_theme_dark_onBackground,
    surface = md_theme_dark_surface,
    onSurface = md_theme_dark_onSurface,
    surfaceVariant = md_theme_dark_surfaceVariant,
    onSurfaceVariant = md_theme_dark_onSurfaceVariant,
    outline = md_theme_dark_outline,
    inverseOnSurface = md_theme_dark_inverseOnSurface,
    inverseSurface = md_theme_dark_inverseSurface,
    inversePrimary = md_theme_dark_inversePrimary,
    surfaceTint = md_theme_dark_surfaceTint,
    outlineVariant = md_theme_dark_outlineVariant,
    scrim = md_theme_dark_scrim,
)

@Composable
fun WoofTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    // Dynamic color is available on Android 12+
    dynamicColor: Boolean = false,
    content: @Composable () -> Unit
) {
    val colorScheme = when {
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            val context = LocalContext.current
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
        }

        darkTheme -> DarkColors
        else -> LightColors
    }
    val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            setUpEdgeToEdge(view, darkTheme)
        }
    }

    MaterialTheme(
        colorScheme = colorScheme,
        shapes = Shapes,
        typography = Typography,
        content = content
    )
}

/**
 * Sets up edge-to-edge for the window of this [view]. The system icon colors are set to either
 * light or dark depending on whether the [darkTheme] is enabled or not.
 */
private fun setUpEdgeToEdge(view: View, darkTheme: Boolean) {
    val window = (view.context as Activity).window
    WindowCompat.setDecorFitsSystemWindows(window, false)
    window.statusBarColor = Color.Transparent.toArgb()
    val navigationBarColor = when {
        Build.VERSION.SDK_INT >= 29 -> Color.Transparent.toArgb()
        Build.VERSION.SDK_INT >= 26 -> Color(0xFF, 0xFF, 0xFF, 0x63).toArgb()
        // Min sdk version for this app is 24, this block is for SDK versions 24 and 25
        else -> Color(0x00, 0x00, 0x00, 0x50).toArgb()
    }
    window.navigationBarColor = navigationBarColor
    val controller = WindowCompat.getInsetsController(window, view)
    controller.isAppearanceLightStatusBars = !darkTheme
    controller.isAppearanceLightNavigationBars = !darkTheme
}

Pemetaan warna

a. Dalam fungsi composable DogItem(), panggil fungsi Card() dan masukkan fungsi Row() ke dalamnya.

b. Karena Card adalah composable turunan pertama di DogItem(), teruskan modifier dari DogItem() ke Card, dan update modifier Row menjadi instance baru Modifier.

Card(modifier = modifier) {
   Row(
       modifier = Modifier
           .fillMaxWidth()
           .padding(dimensionResource(id = R.dimen.padding_small))
   ) {
       DogIcon(dog.imageResourceId)
       DogInformation(dog.name, dog.age)
   }
}

Mengatur ukuran dengan file dimensi

a. Buka file dimens.xml melalui app > res > values > dimens.xml. Terdapat fungsi yang menyimpan nilai dimensi untuk padding_small, padding_medium, dan image_size. Dimensi ini dapat digunakan di seluruh aplikasi Woof.

<resources>
   <dimen name="padding_small">8dp</dimen>
   <dimen name="padding_medium">16dp</dimen>
   <dimen name="image_size">64dp</dimen>
</resources>

b. Pada file MainActivity.kt di fungsi WoofApp(), tambahkan modifier dengan padding_small dalam panggilan ke DogItem(). Untuk menggunakan padding_small, gunakan dimensionResource(id = R.dimen.padding_small).

@Composable
fun WoofApp() {
    Scaffold { it ->
        LazyColumn(contentPadding = it) {
            items(dogs) {
                DogItem(
                    dog = it,
                    modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
                )
            }
        }
    }
}

Preview Light Theme dan Dark Theme

Untuk melihat preview dari tema terang dan tema gelap, panggil fungsi anotasi @Preview dan @Composable di atas fungsi yang memanggil aplikasi dengan tema terang/gelap.

a. Buat fungsi baru bernama WoofPreview() dan WoofDarkThemePreview(), anotasikan keduanya dengan @Preview dan @Composable.

b. Di dalam kedua fungsi, tambahkan WoofTheme(). Kemudian, isi parameter darkTheme ke false untuk tema terang dan isi parameter darkTheme ke true untuk tema gelap.

c. Panggil fungsi WoofApp() di dalam WoofTheme().

@Preview
@Composable
fun WoofPreview() {
    WoofTheme(darkTheme = false) {
        WoofApp()
    }
}
@Preview
@Composable
fun WoofDarkThemePreview() {
   WoofTheme(darkTheme = true) {
       WoofApp()
   }
}

 

2. Menambahkan Bentuk

Menerapkan bentuk akan sangat memengaruhi tampilan composable. Banyak bentuk ditentukan menggunakan fungsi RoundedCornerShape, yang menggambarkan persegi panjang dengan sudut membulat. Angka yang diteruskan menentukan kebulatan sudut. Nilai RoundedCornerShape(0.dp) akan membentuk persegi panjang yang tidak memiliki sudut membulat, sedangkan nilai RoundedCornerShape(50.dp) akan membentuk sudut yang membulat sepenuhnya. File Shape.kt digunakan untuk menentukan bentuk komponen di Compose. Ada tiga jenis komponen: kecil, sedang, dan besar. Di bagian ini, komponen Card akan diubah, yang ditentukan sebagai ukuran medium.

Membentuk gambar anjing menjadi bentuk lingkaran

a. Pada file Shape.kt perhatikan bahwa parameter small diisi nilai RoundedCornerShape(50.dp). Parameter ini akan digunakan untuk membentuk gambar anjing menjadi lingkaran.

val Shapes = Shapes(
   small = RoundedCornerShape(50.dp),
)

b. Pada MainActivity.kt di fungsi DogIcon(), tambahkan atribut clip ke modifier dari Image yang akan memotong gambar menjadi sebuah bentuk. Isi atribut clip dengan nilai MaterialTheme.shapes.small.

c. Masih di fungsi DogIcon(), untuk membuat semua foto menjadi lingkaran, tambahkan atribut ContentScale.Crop untuk memotong gambar agar sesuai dan menjadi bentuk lingkaran sempurna. Atribut contentScale bukanlah atribut dari modifier, melainkan atribut dari Image.

Berikut adalah kode lengkap dari fungsi DogIcon().

@Composable
fun DogIcon(
    @DrawableRes dogIcon: Int,
    modifier: Modifier = Modifier
) {
    Image(
        modifier = modifier
            .size(dimensionResource(R.dimen.image_size))
            .padding(dimensionResource(R.dimen.padding_small))
            .clip(MaterialTheme.shapes.small),
        contentScale = ContentScale.Crop,
        painter = painterResource(dogIcon),

        // Content Description is not needed here - image is decorative, and setting a null content
        // description allows accessibility services to skip this element during navigation.

        contentDescription = null
    )
}

Berikut adalah tampilan gambar yang ada di WoofPreview(). Gambar/ikon anjing sudah berbentuk lingkaran sempurna.



Mengubah bentuk item card

Buja file Shape.kt. Card adalah komponen medium, sehingga objek Shapes perlu ditambahkan parameter medium. Untuk aplikasi Woof ini, pojok kanan atas dan kiri bawah item daftar akan dibentuk sedikit melengkung, tetapi tidak membentuk lingkaran penuh. Oleh karena itu, isi nilai 16.dp ke atribut medium.

medium = RoundedCornerShape(bottomStart = 16.dp, topEnd = 16.dp)

Secara default, Card sudah menggunakan ukuran medium pada objek, jadi tidak perlu untuk menyetel secara eksplisit ke bentuk medium.

3. Menambahkan Tipografi

Platform Android menyediakan berbagai font, tetapi mungkin developer ingin menyesuaikan aplikasi dengan font yang tidak disediakan secara default. Font kustom dapat menambah karakteristik dan digunakan untuk branding. Di bagian ini, akan ditambahkan 3 font khusus, yaitu Abril Fatface, Montserrat Bold, dan Montserrat Regular. Beberapa properti/atribut yang akan digunakan adalah displayLarge, displayMedium, dan bodyLarge.

Membuat Direktori Resource Android untuk font

a. Di tampilan project Android Studio, klik kanan folder res.

b. Pilih New > Android Resource Directory.

c. Beri nama direktori font, isi tipe Resource font, dan klik OK.

d. Buka direktori resource font baru yang terletak di res > font.

Mendownload custom font

a. Buka https://fonts.google.com/.

b. Telusuri Montserrat, lalu klik Download family.

c. Buka file zip.

d. Buka folder Montserrat yang didownload. Di dalam folder static, temukan file Montserrat-Bold.ttf dan Montserrat-Regular.ttf (ttf adalah singkatan dari TrueType Font dan merupakan format untuk file font). Pilih kedua font dan tarik ke direktori resource font dalam project di Android Studio.

e. Di folder font, ganti nama Montserrat-Bold.ttf menjadi montserrat_bold.ttf dan ganti nama Montserrat-Regular.ttf menjadi montserrat_regular.ttf.

f. Telusuri Abril Fatface dan klik Download family.

g. Buka folder Abril_Fatface yang telah didownload. Pilih file AbrilFatface-Regular.ttf, lalu tarik ke direktori resource font.

h. Di folder font, ganti nama Abril_Fatface_Regular.ttf menjadi abril_fatface_regular.ttf.

Inisialisasi font

a. Buka ui.theme > Type.kt. Lakukan inisialisasi dari font yang sudah didownload dan di atas val Typography. Pertama, lakukan inisialisasi Abril Fatface dengan memanggil fungsi FontFamily dan meneruskan Font dengan file font abril_fatface_regular.

b. Lakukan inisialisasi Montserrat dengan memanggil fungsi FontFamily dan meneruskan Font dengan file font montserrat_regular. Untuk montserrat_bold, sertakan juga FontWeight.Bold.

@Composable
fun DogInformation(
   @StringRes dogName: Int,
   dogAge: Int,
   modifier: Modifier = Modifier
) {
   Column(modifier = modifier) {
       Text(
           text = stringResource(dogName),
           style = MaterialTheme.typography.displayMedium,
           modifier = Modifier.padding(top = dimensionResource(id = R.dimen.padding_small))
       )
       Text(
           text = stringResource(R.string.years_old, dogAge),
           style = MaterialTheme.typography.bodyLarge
       )
   }
}

c. Untuk atribut displayLarge, panggil fungsi TextStyle, lalu isi fontFamily, fontWeight, dan fontSize dengan nilai yang ditentukan. Untuk kasus ini, semua teks yang ditetapkan ke displayLarge akan memiliki Abril Fatface sebagai font, dengan ketebalan font normal, dan fontSize 36.sp. Ulangi proses yang sama untuk displayMedium, labelSmall, dan bodyLarge.

import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.sp

val Typography = Typography(
   displayLarge = TextStyle(
       fontFamily = AbrilFatface,
       fontWeight = FontWeight.Normal,
       fontSize = 36.sp
   ),
   displayMedium = TextStyle(
       fontFamily = Montserrat,
       fontWeight = FontWeight.Bold,
       fontSize = 20.sp
   ),
   labelSmall = TextStyle(
       fontFamily = Montserrat,
       fontWeight = FontWeight.Bold,
       fontSize = 14.sp
   ),
   bodyLarge = TextStyle(
       fontFamily = Montserrat,
       fontWeight = FontWeight.Normal,
       fontSize = 14.sp
   )
)

Menambahkan tipografi ke aplikasi

a. Tambahkan displayMedium sebagai gaya untuk dogName karena merupakan informasi singkat yang penting. Tambahkan bodyLarge sebagai gaya untuk dogAge karena berfungsi cukup baik dengan ukuran teks yang lebih kecil.

@Composable
fun DogInformation(
   @StringRes dogName: Int,
   dogAge: Int,
   modifier: Modifier = Modifier
) {
   Column(modifier = modifier) {
       Text(
           text = stringResource(dogName),
           style = MaterialTheme.typography.displayMedium,
           modifier = Modifier.padding(top = dimensionResource(id = R.dimen.padding_small))
       )
       Text(
           text = stringResource(R.string.years_old, dogAge),
           style = MaterialTheme.typography.bodyLarge
       )
   }
}

b. Pada WoofPreview(), nama anjing akan menampilkan font Montserrat tebal dengan ukuran 20.sp, dan usia anjing menampilkan font Montserrat normal dengan ukuran 14.sp. Berikut adalah tampilan dari WoofPreview().

4. Menambahkan Panel Atas Aplikasi


Menambahkan gambar dan teks ke panel atas

a. Di MainActivity.kt, buat composable bernama WoofTopAppBar() dengan modifier opsional.

@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {

}

b. Pada fungsi WoofApp(), nilai contentWindowInsets diteruskan ke LazyColumn sebagai contentPadding.

c. Dalam Scaffold, tambahkan atribut topBar dan isi dengan WoofTopAppBar().

@Composable
fun WoofApp() {
    Scaffold(
        topBar = {
            WoofTopAppBar()
        }
    ) { it ->
        LazyColumn(contentPadding = it) {
            items(dogs) {
                DogItem(
                    dog = it,
                    modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
                )
            }
        }
    }
}

d. Di dalam composable WoofTopAppBar(), panggil fungsi CenterAlignedTopAppBar() dan isi parameter modifier dengan nilai modifier pada fungsi WoofTopAppBar().

e. Isi parameter title dengan memanggil fungsi Row yang akan menyimpan Image dan Text dari CenterAlignedTopAppBar().

f. Tambahkan logo Image ke Row. Set ukuran gambar di modifier dengan nilai image_size yang ada pada file dimens.xml dan juga set padding dengan nilai padding_small yang ada pada file dimens.xml. Untuk mengisi gambar/ikon aplikasi, di atribut painter panggil fungsi painterResource() dengan nilai R.drawable.ic_woof_logo. Sedangkan atribut contentDescription diisi dengan nilai null.

g. Selanjutnya, tambahkan fungsi Text di dalam Row setelah Image. Untuk isi teks, gunakan nama aplikasi yang berada di file strings.xml dengan cara memanggil fungsi stringResource() dan isi dengan nilai R.string.app_name. Isi atribut style pada teks ke displayLarge karena nama aplikasi singkat dan penting.

h. Untuk memperbaiki posisi ikon aplikasi dan nama aplikasi yang tidak sejajar, di fungsi Row, tambahkan parameter verticalAlignment dengan nilai Alignment.CenterVertically.

Berikut adalah kode lengkap fungsi WoofTopAppBar().

@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
   CenterAlignedTopAppBar(
       title = {
           Row(
               verticalAlignment = Alignment.CenterVertically
           ) {
               Image(
                   modifier = Modifier
                       .size(dimensionResource(id = R.dimen.image_size))
                       .padding(dimensionResource(id = R.dimen.padding_small)),
                   painter = painterResource(R.drawable.ic_woof_logo),

                   contentDescription = null
               )
               Text(
                   text = stringResource(R.string.app_name),
                   style = MaterialTheme.typography.displayLarge
               )
           }
       },
       modifier = modifier
   )
}

Preview panel atas aplikasi

Berikut adalah preview dari panel atas aplikasi. Panel atas ini berisi ikon aplikasi yang berupa gambar telapak kaki anjing dan teks berupa nama aplikasi, yaitu Woof.


Hasil Akhir

Berikut adalah tampilan atau hasil akhir dari proyek Material Theming - Woof Application. Gambar di bawah menunjukkan perbedaan ketika awal aplikasi (starter) sebelum dimodifikasi dengan Material Theming dengan hasil akhir aplikasi setelah dimodifikasi dengan Material Theming.

 

 

Berikut adalah link video demo aplikasi Woof Application

https://youtu.be/0fOZ9oMs6dE

Referensi

https://developer.android.com/courses/pathways/android-basics-compose-unit-3-pathway-3?hl=id

https://developer.android.com/codelabs/basic-android-kotlin-compose-material-theming?hl=id&continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fandroid-basics-compose-unit-3-pathway-3%3Fhl%3Did%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fbasic-android-kotlin-compose-material-theming#0


Komentar

Postingan populer dari blog ini

ETS PPB

Tugas 10 PPB