Sabtu, 18 Mei 2024
Rabu, 15 Mei 2024
ImageScrollApp
Pada kesempatan kali ini saya mencoba membuat app scroll dengan menampilan gambar buah, kita dapat melakukan scroll dengan gulir horizontal. Menggunakan Jetpack Compose dan desain material, aplikasi ini memberikan pengalaman visual yang menarik dan responsif.
Fitur Utama:
Tampilan Gulir Horizontal:
- Menggunakan komponen
LazyRow
untuk menampilkan daftar gambar buah secara horizontal dengan jarak antar item yang diatur. - Setiap gambar buah ditampilkan dalam komponen
Card
untuk memberikan efek bayangan dan bentuk yang bulat.
- Menggunakan komponen
Desain Material:
- Aplikasi ini menggunakan desain material modern untuk memberikan tampilan yang bersih dan konsisten.
- Teks judul "Fruit Image Scroll" menggunakan berbagai teknik styling seperti warna tema, ukuran font yang disesuaikan, efek bayangan, dan latar belakang berwarna dengan sudut yang bulat.
Komposisi Jetpack Compose:
- Menggunakan Jetpack Compose untuk membuat UI yang deklaratif dan responsif.
- Setiap komponen UI didefinisikan dalam fungsi
Composable
, memungkinkan kode yang lebih bersih dan mudah dipelihara.
Responsif dan Dinamis:
- UI responsif yang menyesuaikan dengan ukuran layar perangkat.
- Animasi dan interaksi yang halus untuk pengalaman pengguna yang lebih baik.
Berikut adalah source code:
package com.example.fruiteimagescroll
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.fruiteimagescroll.ui.theme.FruiteImageScrollTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FruiteImageScrollTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
FruitImageScroll()
}
}
}
}
}
@Composable
fun FruitImageScroll() {
val fruits = listOf(
R.drawable.img1,
R.drawable.img2,
R.drawable.img3,
R.drawable.img4,
R.drawable.img5,
R.drawable.img6,
R.drawable.img7,
R.drawable.img8,
R.drawable.img9,
R.drawable.img10,
)
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Fruit Image Scroll",
style = MaterialTheme.typography.headlineSmall.copy(
fontSize = 24.sp,
color = MaterialTheme.colorScheme.primary
),
modifier = Modifier
.padding(bottom = 16.dp)
.shadow(4.dp, RoundedCornerShape(8.dp))
.padding(16.dp),
textAlign = TextAlign.Center
)
LazyRow(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxWidth()
) {
items(fruits.size) { index ->
Card(
shape = RoundedCornerShape(8.dp),
elevation = CardDefaults.cardElevation(4.dp),
modifier = Modifier
.size(150.dp)
.clip(RoundedCornerShape(8.dp))
) {
Image(
painter = painterResource(id = fruits[index]),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun FruitImageScrollPreview() {
FruiteImageScrollTheme {
FruitImageScroll()
}
}
Berikut adalah tampilannya:
Rabu, 01 Mei 2024
woofApp
Kali ini saya belajar untuk membuat aplikasi woof yaitu aplikasi yang menampilkan daftar anjing dimana menerapkan desain material dengan jetpack compose. Desain Material adalah sistem desain yang dibuat dan didukung oleh desainer dan developer Google guna menciptakan pengalaman digital berkualitas tinggi untuk Android, serta platform seluler dan web lainnya. Panduan ini berisi langkah-langkah cara membangun UI aplikasi Anda dengan cara yang mudah dibaca, menarik, dan konsisten.
@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
}
Di MainActivity.kt, WoofTheme() ditambahkan untuk menyediakan Penerapan Tema Material untuk seluruh aplikasi.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WoofTheme {
Surface(
modifier = Modifier.fillMaxSize()
) {
WoofApp()
}
}
}
}
}
Lihat WoofPreview(). WoofTheme() ditambahkan untuk menyediakan Penerapan Tema Material yang Anda lihat di WoofPreview().@Preview
@Composable
fun WoofPreview() {
WoofTheme(darkTheme = false) {
WoofApp()
}
}
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-woof.git $ cd basic-android-kotlin-compose-training-woof $ git checkout starter
- Buka com.example.woof > data > Dog.kt. File ini berisi Dog data class yang akan digunakan untuk mewakili foto, nama, usia, dan hobi anjing. File ini juga berisi daftar anjing dan informasi yang akan Anda gunakan sebagai data di aplikasi Anda.
- Buka res > drawable. File ini berisi semua aset gambar yang Anda butuhkan untuk project ini, termasuk ikon aplikasi, gambar anjing, dan ikon.
- Buka res > values > strings.xml. File ini berisi string yang Anda gunakan dalam aplikasi ini, termasuk nama aplikasi, nama anjing, deskripsinya, dan lainnya.
- Buka MainActivity.kt. File ini berisi kode untuk membuat daftar sederhana yang menampilkan foto anjing, nama anjing, dan usia anjing tersebut.
- WoofApp() berisi LazyColumn yang menampilkan DogItem.
- DogItem() berisi Row yang menampilkan foto anjing dan informasi tentangnya.
- DogIcon() menampilkan foto anjing.
- DogInformation() menampilkan nama dan usia anjing.
- WoofPreview() memungkinkan Anda melihat pratinjau aplikasi di panel Design.
###Menambahkan Warna
Hal pertama yang akan Anda ubah di aplikasi Woof adalah skema warna.
Skema warna adalah kombinasi warna yang digunakan aplikasi Anda. Kombinasi warna yang berbeda membangkitkan suasana hati yang berbeda, yang memengaruhi perasaan orang saat menggunakan aplikasi Anda.
Warna, dalam sistem Android, diwakili oleh nilai warna heksadesimal (hex). Kode warna heksadesimal dimulai dengan tanda pagar (#), dan diikuti dengan enam huruf dan/atau angka yang mewakili komponen merah, hijau, dan biru (RGB) dari warna tersebut. Dua huruf/angka pertama merujuk ke warna merah, dua huruf berikutnya berwarna hijau, dan dua huruf terakhir mengacu pada warna biru.
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
}
- Jika dynamicColor bernilai benar dan versi build adalah S atau yang lebih tinggi, perangkat akan diperiksa apakah menggunakan darkTheme atau tidak.
- Jika temanya gelap, colorScheme akan disetel ke dynamicDarkColorScheme.
- Jika tidak dalam tema gelap, warna akan disetel ke dynamicLightColorScheme.
- Jika aplikasi tidak menggunakan dynamicColorScheme, aplikasi akan diperiksa apakah menggunakan darkTheme. Jika demikian, colorScheme akan ditetapkan ke DarkColors.
- Jika tidak ada yang benar, colorScheme akan ditetapkan ke LightColors.
al 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
}
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)
}
}
<resources>
<dimen name="padding_small">8dp</dimen>
<dimen name="padding_medium">16dp</dimen>
<dimen name="image_size">64dp</dimen>
</resources>
@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() {
}
@Preview
@Composable
fun WoofDarkThemePreview() {
WoofTheme(darkTheme = true) {
}
}
@Preview
@Composable
fun WoofDarkThemePreview() {
WoofTheme(darkTheme = true) {
WoofApp()
}
}

- Buka aplikasi Setelan di perangkat.
- Telusuri Tema Gelap dan klik di dalamnya.
- Aktifkan/Nonaktifkan Tema gelap.
- Buka kembali aplikasi Woof, dan aplikasi akan muncul dalam tema gelap
fun WoofTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
)
2. Untuk mengubah latar belakang perangkat atau emulator, buka Setelan, lalu cari Wallpaper.3. Ubah wallpaper ke warna atau sekumpulan warna.
4. Jalankan ulang aplikasi Anda untuk melihat tema dinamis (perhatikan bahwa perangkat atau emulator anda harus Android 12+ untuk melihat warna dinamis), jangan ragu untuk mencoba fitur ini dengan wallpaper yang berbeda.
@Composable
fun WoofTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = false,
content: @Composable () -> Unit
)
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
)
}
medium = RoundedCornerShape(bottomStart = 16.dp, topEnd = 16.dp)
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
- Buka https://fonts.google.com/.
- Telusuri Montserrat, lalu klik Download family.
- Buka file zip.
- Buka folder Montserrat yang didownload. Di folder static, temukan 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 Anda di Android Studio
- Di folder font, ganti nama Montserrat-Bold.ttf menjadi montserrat_bold.ttf dan ganti nama Montserrat-Regular.ttf menjadi montserrat_regular.ttf.
- Telusuri Abril Fatface dan klik Download family.
- Buka folder Abril_Fatface yang telah didownload. Pilih AbrilFatface-Regular.ttf, lalu tarik ke direktori resource font.
- Di folder font, ganti nama Abril_Fatface_Regular.ttf menjadi abril_fatface_regular.ttf.
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import com.example.woof.R
val AbrilFatface = FontFamily(
Font(R.font.abril_fatface_regular)
)
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)
)
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
)
)
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
@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
)
}
}

Berikut ini tampilan item daftar secara berdampingan sebelum dan sesudah menambahkan tipografi. Perhatikan perbedaan font antara nama anjing dan usia anjing.
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
}
@Composable
fun WoofApp() {
Scaffold { it ->
LazyColumn(contentPadding = it) {
items(dogs) {
DogItem(
dog = it,
modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
)
}
}
}
}
Scaffold(
topBar = {
WoofTopAppBar()
}
)
@Composable
fun WoofApp() {
Scaffold(
topBar = {
WoofTopAppBar()
}
) { it ->
LazyColumn(contentPadding = it) {
items(dogs) {
DogItem(
dog = it,
modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
)
}
}
}
}
import androidx.compose.material3.CenterAlignedTopAppBar
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
CenterAlignedTopAppBar(
modifier = modifier
)
}
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier){
CenterAlignedTopAppBar(
title = {
Row() {
}
},
modifier = modifier
)
}
- Setel ukuran gambar di modifier sebagai image_size dalam file dimens.xml dan padding sebagai padding_small dari file dimens.xml.
- Gunakan painter untuk menetapkan Image sebagai ic_woof_logo dari folder drawable.
- Tetapkan contentDescription sebagai null. Dalam situasi ini, logo aplikasi tidak menambahkan informasi semantik apa pun bagi pengguna dengan gangguan penglihatan, sehingga kita tidak perlu menambahkan deskripsi konten.
Row() {
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
)
}
- Gunakan stringResource() untuk menetapkannya ke nilai app_name. Tindakan ini akan menetapkan teks ke nama aplikasi, yang disimpan di strings.xml.
- Setel gaya teks ke displayLarge karena nama aplikasi singkat dan penting.
@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
)
}

-
Pada kesempatan ini saya akan meampilkan ucapan happy birthday dengan menggunakan jetpack compose. Jetpack Compose adalah toolkit modern unt...