Tugas 8 - Membuat Image Scroll dengan Desain Material
Moch. Avin (5025221061)
Pemrograman Perangkat Bergerak - PPB G
Link Repo Github: https://github.com/mochavin/ppb-Image-Scroll-affirmation
Membuat Daftar Gambar Bergulir (Image Scroll) di Android dengan Jetpack Compose
Langkah 1: Menyiapkan Model Data
Buat file Affirmation.kt di dalam app/src/main/java/com/example/affirmations/model/:
package com.example.affirmations.model
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
data class Affirmation(
@StringRes val stringResourceId: Int,
@DrawableRes val imageResourceId: Int
)
Langkah 2: Membuat Sumber Data (Datasource)
Buat file Datasource.kt di dalam app/src/main/java/com/example/affirmations/data/:
package com.example.affirmations.data
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
class Datasource() {
fun loadAffirmations(): List<Affirmation> {
return listOf<Affirmation>(
Affirmation(R.string.affirmation1, R.drawable.image1),
Affirmation(R.string.affirmation2, R.drawable.image2),
Affirmation(R.string.affirmation3, R.drawable.image3),
Affirmation(R.string.affirmation4, R.drawable.image4),
Affirmation(R.string.affirmation5, R.drawable.image5),
Affirmation(R.string.affirmation6, R.drawable.image6),
Affirmation(R.string.affirmation7, R.drawable.image7),
Affirmation(R.string.affirmation8, R.drawable.image8),
Affirmation(R.string.affirmation9, R.drawable.image9),
Affirmation(R.string.affirmation10, R.drawable.image10))
}
}
Langkah 3: Mendesain Item Kartu (AffirmationCard)
Dalam app/src/main/java/com/example/affirmations/MainActivity.kt
@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
Card (modifier = modifier) {
Column {
Image(
painter = painterResource(affirmation.imageResourceId),
contentDescription = stringResource(affirmation.stringResourceId),
modifier = Modifier
.fillMaxWidth()
.height(194.dp),
contentScale = ContentScale.Crop
)
Text(
text = LocalContext.current.getString(affirmation.stringResourceId),
modifier = Modifier.padding(16.dp),
style = MaterialTheme.typography.headlineSmall
)
}
}
}
@Preview
@Composable
private fun AffirmationCardPreview() {
AffirmationCard(Affirmation(R.string.affirmation1, R.drawable.image1))
}
Penjelasan:
- Card: Composable yang menyediakan tampilan kartu dengan elevasi dan sudut membulat.
- Column: Menata Image dan Text secara vertikal.
- Image: Menampilkan gambar.
- painterResource(affirmation.imageResourceId): Memuat gambar dari resource drawable.
- contentDescription: Teks deskriptif untuk aksesibilitas.
- Modifier.fillMaxWidth().height(194.dp): Membuat gambar mengisi lebar kartu dan memiliki tinggi tetap.
- contentScale = ContentScale.Crop: Mengatur bagaimana gambar diskalakan agar sesuai dengan batasnya. Crop akan memastikan gambar mengisi area dan memotong bagian yang berlebih, menjaga rasio aspek.
- Text: Menampilkan teks afirmasi.
- LocalContext.current.getString(affirmation.stringResourceId): Mengambil string dari resource.
- MaterialTheme.typography.headlineSmall: Menerapkan gaya teks yang telah ditentukan tema.
Langkah 4: Membuat Daftar Bergulir dengan LazyColumn
Tambahkan fungsi Composable AffirmationsList di MainActivity.kt:
@Composable
fun AffirmationsList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
LazyColumn(modifier = modifier) {
items(affirmationList) { affirmation ->
AffirmationCard(
affirmation = affirmation,
modifier = Modifier.padding(8.dp)
)
}
}
}
Penjelasan:
- LazyColumn: Composable dasar untuk daftar vertikal yang bisa digulir.
- items(affirmationList): Blok ini akan dipanggil untuk setiap Affirmation dalam affirmationList.
- Di dalam blok items, kita memanggil AffirmationCard yang telah kita buat, meneruskan objek affirmation saat ini.
- Modifier.padding(8.dp) pada AffirmationCard memberikan sedikit ruang di sekitar setiap kartu
Langkah 5: Menggabungkan Semuanya
berikut isi dari MainActivity.kt:
package com.example.affirmations
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Card
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.affirmations.data.Datasource
import com.example.affirmations.model.Affirmation
import com.example.affirmations.ui.theme.AffirmationsTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AffirmationsTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
AffirmationsApp()
}
}
}
}
}
@Composable
fun AffirmationsApp() {
val layoutDirection = LocalLayoutDirection.current
Surface (
modifier = Modifier
.fillMaxSize()
.statusBarsPadding()
.padding(
start = WindowInsets.safeDrawing.asPaddingValues()
.calculateStartPadding(layoutDirection),
end = WindowInsets.safeDrawing.asPaddingValues()
.calculateEndPadding(layoutDirection)
)
){
AffirmationsList(
affirmationList = Datasource().loadAffirmations()
)
}
}
@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
Card (modifier = modifier) {
Column {
Image(
painter = painterResource(affirmation.imageResourceId),
contentDescription = stringResource(affirmation.stringResourceId),
modifier = Modifier
.fillMaxWidth()
.height(194.dp),
contentScale = ContentScale.Crop
)
Text(
text = LocalContext.current.getString(affirmation.stringResourceId),
modifier = Modifier.padding(16.dp),
style = MaterialTheme.typography.headlineSmall
)
}
}
}
@Preview
@Composable
private fun AffirmationCardPreview() {
AffirmationCard(Affirmation(R.string.affirmation1, R.drawable.image1))
}
@Composable
fun AffirmationsList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
LazyColumn(modifier = modifier) {
items(affirmationList) { affirmation ->
AffirmationCard(
affirmation = affirmation,
modifier = Modifier.padding(8.dp)
)
}
}
}

Comments
Post a Comment