Tugas Pertemuan 7 - Membuat Aplikasi Woof
Tugas Pertemuan 7
Membuat Aplikasi Woof
NRP : 5025201046
Kelas : Pemrograman Perangkat Bergerak B
Tahun : 2024
Deskripsi Singkat Aplikasi
Aplikasi bernama Woof ini merupakan aplikasi yang menampilkan daftar anjing. Aplikasi ini menggunakan Desain Material untuk membuat pengalaman aplikasi yang menarik.
Download Kode Awal
Download Zip Kode Awal
Mempelajari Kode Awal
1. Buka kode awal di Android Studio.
2. File com.example.woof > data > Dog.kt berisi Dog data class yang mewakili foto, nama, usia, dan hobi anjing, serta berisi daftar anjing dan informasi yang digunakan sebagai data di aplikasi.
3. Forder res > drawable berisi semua aset gambar termasuk ikon aplikasi, gambar anjing, dan ikon.
4. File res > values > strings.xml berisi string yang digunakan dalam aplikasi, termasuk nama aplikasi, nama anjing, deskripsinya, dan lainnya.
5. File MainActivity.kt berisi kode untuk membuat daftar sederhana yang menampilkan foto dan informasi anjing tersebut.
6. WoofApp() berisi LazyColumn yang menampilkan DogItem.
7. DogItem() berisi Row yang menampilkan foto dan informasi anjing.
8. DogIcon() menampilkan foto anjing.
9. DogInformation() menampilkan informasi anjing berupa nama dan usia.
10. WoofPreview() menampilkan pratinjau aplikasi di panel Design.
Tampilan kode awal beserta pratinjau aplikasi. |
Memastikan Emulator/Perangkat Bertema Terang
1. Buka aplikasi Setelan di perangkat.
2. Telusuri Tema gelap dan klik di dalamnya.
3. Nonaktifkan, jika Tema gelap aktif.
Setelan Tema gelap di perangkat. |
Menambahkan Warna
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)
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 }
Card() { Row( modifier = modifier .fillMaxWidth() .padding(dimensionResource(id = R.dimen.padding_small)) ) { DogIcon(dog.imageResourceId) DogInformation(dog.name, dog.age) } }
Card(modifier = modifier) { Row( modifier = Modifier .fillMaxWidth() .padding(dimensionResource(id = R.dimen.padding_small)) ) { DogIcon(dog.imageResourceId) DogInformation(dog.name, dog.age) } }
Pratinjau aplikasi |
File Dimensi
@Composable fun WoofApp() { Scaffold { it -> LazyColumn(contentPadding = it) { items(dogs) { DogItem( dog = it, modifier = Modifier.padding(dimensionResource(R.dimen.padding_small)) ) } } } }
@Preview @Composable fun WoofDarkThemePreview() { WoofTheme(darkTheme = true) { WoofApp() } }
Tampilan pratinjau dalam Tema gelap |
2. Ubah pengaturan tema gelap di perangkat/emulator.
Tampilan Tema gelap di perangkat atau emulator. |
3. Karena fokus aplikasi saat ini pada Tema terang, kembalikan setelan aplikasi dengan menonaktifkan tema gelap.
Warna Dinamis
@Composable fun WoofTheme( darkTheme: Boolean = isSystemInDarkTheme(), dynamicColor: Boolean = true, content: @Composable () -> Unit )
Tampilan aplikasi dengan warna dinamis. |
2. Karena fokus aplikasi saat ini, yaitu tema custom. kembalikan dynamicColor menjadi false.
@Composable fun WoofTheme( darkTheme: Boolean = isSystemInDarkTheme(), dynamicColor: Boolean = false, content: @Composable () -> Unit )
Menambahkan Bentuk
Membentuk gambar anjing menjadi lingkaran
val Shapes = Shapes( small = RoundedCornerShape(50.dp), )
import androidx.compose.ui.draw.clip @Composable fun DogIcon( @DrawableRes dogIcon: Int, modifier: Modifier = Modifier ) { Image( modifier = modifier .size(dimensionResource(id = R.dimen.image_size)) .padding(dimensionResource(id = R.dimen.padding_small)) .clip(MaterialTheme.shapes.small),
import androidx.compose.ui.layout.ContentScale @Composable fun DogIcon( @DrawableRes dogIcon: Int, modifier: Modifier = Modifier ) { Image( modifier = modifier .size(dimensionResource(id = R.dimen.image_size)) .padding(dimensionResource(id = R.dimen.padding_small)) .clip(MaterialTheme.shapes.small), contentScale = ContentScale.Crop,
@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 ) }
Pratinjau aplikasi dengan foto anjing lingkaran menggunakan contentScale dan Crop. |
Menambahkan bentuk ke item daftar
1. Buka file Shape.kt. Card adalah komponen media, sehingga Anda menambahkan parameter media objek Shapes. Untuk aplikasi ini, pojok kanan atas dan kiri bawah item daftar, tetapi tidak membentuk lingkaran penuh. Untuk mencapainya, teruskan 16.dp ke atribut medium.medium = RoundedCornerShape(bottomStart = 16.dp, topEnd = 16.dp)
Pratinjau aplikasi dengan perubahan bentuk daftar item. |
Menambahkan Tipografi
Membuat Direktori Resource Android font.
Mendownload font kustom
Melakukan Inisialisasi Font
import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight val AbrilFatFace = FontFamily( Font(R.font.abril_fatface_regular) ) val Montserrat = FontFamily( Font(R.font.montserrat_regular), Font(R.font.montserrat_bold, FontWeight.Bold) )
Tabel font |
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 teks aplikasi
@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 ) } }
Menambahkan Panel Atas
@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 ) }
Jalankan Aplikasi
Source Code
https://github.com/rycahayash/WoofApp
Referensi
- 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
- https://kuliahppb.blogspot.com/2024/04/penerapan-tema-material-aplikasi-woof.html
Komentar
Posting Komentar