Placeholder dan Status Error
Tangani pemuatan dan kegagalan dengan baik.
Placeholder dan Status Error adalah pelajaran Android Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Android Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Android Academy mencakup 4 pelajaran total.
Pemuatan Tidak Seketika
Gambar dari jaringan membutuhkan waktu. Selama jeda itu, UI Anda menampilkan... tidak ada apa-apa, kecuali jika Anda menanganinya. Terkadang gambar bahkan tidak pernah tiba: URL rusak, server tidak aktif, atau pengguna sedang luring.
Aplikasi yang rapi menampilkan placeholder saat memuat dan fallback ketika terjadi kegagalan, bukan ruang kosong atau aplikasi yang mogok. Coil memudahkan keduanya.
Dalam pelajaran ini, Anda akan menambahkan placeholder, gambar kesalahan, dan UI khusus untuk setiap status.
Placeholder Sederhana
Cara tercepat untuk menambahkan placeholder adalah meneruskan drawable ke AsyncImage melalui parameter placeholder menggunakan painterResource. Coil akan menampilkannya hingga gambar sebenarnya selesai dimuat.
Gunakan drawable yang netral dan ringan, seperti kotak abu-abu atau siluet logo.
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import coil3.compose.AsyncImage
@Composable
fun ImageWithPlaceholder(url: String) {
AsyncImage(
model = url,
contentDescription = null,
placeholder = painterResource(R.drawable.placeholder_gray)
)
}Menambahkan Gambar Kesalahan
Parameter error menampilkan drawable fallback ketika permintaan gagal. Ada juga fallback, yang digunakan secara khusus ketika model bernilai null (tidak ada data yang perlu dimuat sama sekali).
Dengan mengatur ketiganya—placeholder, error, dan fallback—Anda mencakup setiap status visual dengan hampir tanpa kode tambahan.
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import coil3.compose.AsyncImage
@Composable
fun RobustImage(url: String?) {
AsyncImage(
model = url,
contentDescription = null,
placeholder = painterResource(R.drawable.placeholder_gray),
error = painterResource(R.drawable.image_broken),
fallback = painterResource(R.drawable.no_image)
)
}Placeholder melalui ImageRequest
Anda juga dapat mengatur status-status ini langsung pada ImageRequest. Ini berguna ketika Anda membuat permintaan sekali lalu menggunakannya kembali, atau ketika Anda perlu mengatur opsi permintaan lain pada saat yang sama.
Fungsi pada tingkat permintaan menerima ID resource drawable.
import android.content.Context
import coil3.request.ImageRequest
import coil3.request.crossfade
import coil3.request.error
import coil3.request.placeholder
fun buildRequest(context: Context, url: String) =
ImageRequest.Builder(context)
.data(url)
.crossfade(true)
.placeholder(R.drawable.placeholder_gray)
.error(R.drawable.image_broken)
.build()UI Khusus dengan SubcomposeAsyncImage
Drawable memang cukup, tetapi terkadang Anda menginginkan pemutar, efek kilau, atau teks untuk setiap status. SubcomposeAsyncImage memungkinkan Anda menyediakan composable sungguhan untuk loading, error, dan success.
Solusi ini lebih fleksibel tetapi sedikit lebih berat, jadi utamakan placeholder drawable untuk daftar panjang dan gunakan subcompose untuk gambar utama.
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import coil3.compose.SubcomposeAsyncImage
@Composable
fun HeroImage(url: String) {
SubcomposeAsyncImage(
model = url,
contentDescription = "Hero",
loading = { CircularProgressIndicator() },
error = { Text("Could not load image") }
)
}Membaca Status Secara Langsung
Untuk kontrol penuh, gunakan API rememberAsyncImagePainter dan periksa state-nya. Status tersebut adalah tipe sealed dengan kasus Loading, Success, Error, dan Empty.
Dengan demikian, Anda dapat mengendalikan tata letak, animasi, atau analitik sendiri berdasarkan hal yang terjadi.
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import coil3.compose.AsyncImagePainter
import coil3.compose.rememberAsyncImagePainter
@Composable
fun StateAwareImage(url: String) {
val painter = rememberAsyncImagePainter(model = url)
val state = painter.state.collectAsState().value
when (state) {
is AsyncImagePainter.State.Loading -> { /* show spinner */ }
is AsyncImagePainter.State.Error -> { /* show error UI */ }
else -> Image(painter = painter, contentDescription = null)
}
}Menampilkan Placeholder Kilau
Pola yang populer adalah efek kilau: gradien abu-abu beranimasi yang memberi tanda bahwa konten akan segera muncul. Anda dapat membuat versi sederhana dengan kotak berwarna solid di belakang status pemuatan.
Di sini kita menggunakan SubcomposeAsyncImage dengan kotak berwarna saat memuat. Ganti kotak tersebut dengan pustaka efek kilau jika Anda menginginkan efek animasi.
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import coil3.compose.SubcomposeAsyncImage
@Composable
fun ShimmerImage(url: String) {
SubcomposeAsyncImage(
model = url,
contentDescription = null,
loading = {
androidx.compose.foundation.layout.Box(
Modifier.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceVariant)
)
}
)
}Menangani Model Null atau Kosong
Bagaimana jika Anda belum memiliki URL, misalnya untuk pengguna tanpa foto profil? Meneruskan null sebagai model akan memicu drawable fallback (atau error jika fallback tidak diatur).
Dengan begitu, Anda tidak perlu menangani null secara khusus dalam kode sendiri; biarkan Coil menampilkan avatar default.
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import coil3.compose.AsyncImage
@Composable
fun ProfilePicture(photoUrl: String?) {
// If photoUrl is null, Coil shows the fallback default avatar.
AsyncImage(
model = photoUrl,
contentDescription = "Profile picture",
fallback = painterResource(R.drawable.default_avatar),
error = painterResource(R.drawable.default_avatar)
)
}Mendengarkan Kesalahan dengan Listener
Terkadang Anda perlu merespons melalui kode ketika pemuatan gagal, misalnya untuk mencatatnya atau mencoba lagi. ImageRequest.Builder menerima listener dengan callback keberhasilan dan kesalahan.
Pastikan callback ini tetap ringan; callback tersebut berjalan di thread utama.
import android.content.Context
import android.util.Log
import coil3.request.ImageRequest
fun loggedRequest(context: Context, url: String) =
ImageRequest.Builder(context)
.data(url)
.listener(
onError = { _, result ->
Log.e("Coil", "Load failed", result.throwable)
},
onSuccess = { _, _ ->
Log.d("Coil", "Loaded $url")
}
)
.build()Mewarnai dan Filter Warna
Drawable placeholder dan kesalahan sering terlihat lebih baik jika diberi warna yang sesuai dengan tema Anda. Anda dapat menerapkan ColorFilter pada AsyncImage, yang sangat cocok untuk fallback bergaya ikon monokrom agar dapat menyesuaikan diri dengan mode terang dan gelap.
Terapkan filter hanya pada tampilan placeholder atau kesalahan yang diinginkan; untuk foto sebenarnya, biasanya filter tidak digunakan.
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import coil3.compose.AsyncImage
@Composable
fun TintedFallback(url: String?) {
AsyncImage(
model = url,
contentDescription = null,
error = painterResource(R.drawable.ic_image_placeholder),
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurfaceVariant)
)
}Komponen Gambar yang Tangguh
Mari kita susun komponen yang dapat digunakan kembali dan menangani setiap status dengan rapi: latar belakang saat memuat, fallback saat terjadi kesalahan, crossfade, dan crop. Masukkan komponen ini ke dalam daftar dan Anda tidak perlu lagi mengkhawatirkan ruang kosong.
import androidx.compose.foundation.layout.size
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.res.painterResource
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade
@Composable
fun ResilientImage(url: String?, size: Int = 96) {
val context = LocalContext.current
AsyncImage(
model = ImageRequest.Builder(context)
.data(url)
.crossfade(true)
.build(),
contentDescription = null,
contentScale = ContentScale.Crop,
placeholder = painterResource(R.drawable.placeholder_gray),
error = painterResource(R.drawable.image_broken),
fallback = painterResource(R.drawable.default_avatar),
modifier = Modifier.size(size.dp)
)
}Pemeriksaan Singkat
Anda meneruskan model = null ke AsyncImage. Drawable apa yang ditampilkan Coil secara default?
Rangkuman
Anda telah membuat pemuatan gambar berjalan dengan baik. Poin-poin penting:
placeholderditampilkan saat memuat,errorsaat gagal, danfallbacksaat model bernilai null.- Atur semuanya pada
AsyncImageatauImageRequest. SubcomposeAsyncImagememungkinkan Anda menyediakan composable sungguhan (pemutar, efek berkilau) untuk setiap status.rememberAsyncImagePaintermenyediakanstatementah untuk kendali penuh.- Gunakan
listenerpermintaan untuk mencatat atau merespons hasil pemuatan.
Berikutnya: cache dan performa, agar gambar dimuat secara instan untuk kedua kalinya.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Placeholder dan Status Error” gratis?
Ya — teks lengkap “Placeholder dan Status Error” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Android Academy, upgrade ke CoddyKit PRO. Kursus Android Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Placeholder dan Status Error”?
Tangani pemuatan dan kegagalan dengan baik. Kamu berlatih Android Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Android Academy?
Tidak diperlukan pengalaman sebelumnya. Android Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Placeholder dan Status Error” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Android Academy ini?
Ya. Setiap pelajaran Android Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Memuat Gambar dengan Coil
- Placeholder dan Status Error
- Caching dan Kinerja
- Memutar Audio dan Video