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)
)
}
}
}

Hasil Akhir

Setelah menjalankan aplikasi, akan terlihat daftar kartu yang dapat digulir. Setiap kartu menampilkan gambar di bagian atas dan teks afirmasi di bawahnya. Gambar akan mengisi lebar kartu dan dipotong (cropped) jika aspek rasionya tidak sesuai dengan tinggi yang ditentukan, berkat ContentScale.Crop.






Comments

Popular posts from this blog

Pengumpulan EAS Pemrograman Perangkat Bergerak G

Tugas 5 - Membuat Aplikasi Kalkulator Sederhana

Tugas 6 - Membuat aplikasi currency converter sederhana