Platzhalter und Fehlerzustände
Lade- und Fehlerzustände elegant behandeln
Platzhalter und Fehlerzustände ist eine kostenlose Android Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Android Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Android Academy-Kurs umfasst insgesamt 4 Lektionen.
Laden geschieht nicht sofort
Bilder aus dem Netzwerk benötigen Zeit. Währenddessen zeigt Ihre UI … nichts, sofern Sie diesen Zustand nicht behandeln. Und manchmal kommt das Bild nie an: Die URL ist fehlerhaft, der Server nicht erreichbar oder der Benutzer offline.
Eine ausgereifte App zeigt während des Ladens einen Platzhalter und bei einem Fehler ein Ersatzbild, statt eine leere Fläche oder einen Absturz zu erzeugen. Coil macht beides einfach.
In dieser Lektion fügen Sie Platzhalter, Fehlerbilder und eine eigene UI für die einzelnen Zustände hinzu.
Ein einfacher Platzhalter
Am schnellsten fügen Sie einen Platzhalter hinzu, indem Sie über den Parameter placeholder von AsyncImage ein Drawable mit painterResource übergeben. Coil zeigt es an, bis das eigentliche Bild vollständig geladen ist.
Verwenden Sie ein neutrales, leichtgewichtiges Drawable, etwa ein graues Feld oder die Silhouette eines Logos.
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)
)
}Ein Fehlerbild hinzufügen
Der Parameter error zeigt ein Ersatz-Drawable an, wenn die Anfrage fehlschlägt. Außerdem gibt es fallback, das speziell verwendet wird, wenn das model den Wert null hat, also überhaupt keine zu ladenden Daten vorhanden sind.
Wenn Sie alle drei Optionen festlegen – placeholder, error und fallback –, decken Sie nahezu ohne zusätzlichen Code jeden visuellen Zustand ab.
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)
)
}Platzhalter über ImageRequest
Sie können diese Zustände auch direkt in der ImageRequest festlegen. Das ist praktisch, wenn Sie die Anfrage einmal erstellen und wiederverwenden oder gleichzeitig weitere Anfrageoptionen benötigen.
Die Funktionen auf Anfrageebene erwarten IDs von Drawable-Ressourcen.
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()Eigene UI mit SubcomposeAsyncImage
Drawables sind oft ausreichend, aber manchmal benötigen Sie pro Zustand einen Spinner, einen Schimmer oder Text. Mit SubcomposeAsyncImage können Sie für loading, error und success echte Composables bereitstellen.
Diese Lösung ist flexibler, aber etwas aufwendiger. Bevorzugen Sie daher in langen Listen Drawable-Platzhalter und verwenden Sie Subcompose für besonders hervorgehobene Bilder.
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") }
)
}Den Status direkt auslesen
Für vollständige Kontrolle verwenden Sie die API rememberAsyncImagePainter und untersuchen deren state. Der Status ist ein versiegelter Typ mit den Fällen Loading, Success, Error und Empty.
Damit können Sie Ihr eigenes Layout, Animationen oder Analysen abhängig vom eingetretenen Zustand steuern.
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)
}
}Einen Schimmer-Platzhalter anzeigen
Ein beliebtes Muster ist ein Schimmer: ein animierter grauer Farbverlauf, der andeutet, dass Inhalte geladen werden. Eine einfache Variante können Sie mit einem einfarbigen Feld hinter dem Ladezustand erstellen.
Hier verwenden wir SubcomposeAsyncImage mit einem eingefärbten Feld während des Ladens. Ersetzen Sie das Feld durch eine Schimmer-Bibliothek, wenn Sie den animierten Effekt wünschen.
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)
)
}
)
}Mit einem null- oder leeren Model umgehen
Was ist, wenn Sie noch keine URL haben, etwa bei einem Benutzer ohne Profilbild? Wenn Sie null als Model übergeben, wird das fallback-Drawable ausgelöst – oder error, falls kein Fallback festgelegt ist.
So müssen Sie null nicht in Ihrem eigenen Code gesondert behandeln. Lassen Sie Coil einen Standardavatar anzeigen.
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)
)
}Fehler mit einem Listener erfassen
Manchmal müssen Sie im Code reagieren, wenn das Laden fehlschlägt, etwa um den Fehler zu protokollieren oder einen erneuten Versuch zu starten. ImageRequest.Builder akzeptiert einen listener mit Erfolgs- und Fehler-Callbacks.
Halten Sie diese Callbacks kurz, da sie im Hauptthread ausgeführt werden.
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()Farbton und Farbfilter
Platzhalter- und Fehler-Drawables wirken oft am besten, wenn sie an Ihr Theme angepasst eingefärbt werden. Sie können einen ColorFilter auf ein AsyncImage anwenden. Das eignet sich besonders für einfarbige, symbolartige Ersatzbilder, die sich an den hellen und dunklen Modus anpassen sollen.
Wenden Sie den Filter nur auf den gewünschten Platzhalter- oder Fehlerzustand an. Bei echten Fotos lassen Sie ihn normalerweise deaktiviert.
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)
)
}Eine robuste Bildkomponente
Stellen wir nun eine wiederverwendbare Komponente zusammen, die jeden Zustand sauber behandelt: einen Hintergrund während des Ladens, ein Fehlerbild, Crossfade und Zuschneiden. Fügen Sie sie in eine Liste ein und machen Sie sich keine Gedanken mehr über leere Flächen.
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)
)
}Schnelltest
Sie übergeben model = null an AsyncImage. Welches Drawable zeigt Coil standardmäßig an?
Zusammenfassung
Sie haben das Laden von Bildern robust gestaltet. Die wichtigsten Punkte:
placeholderwird während des Ladens angezeigt,errorbei einem Fehler undfallback, wenn das Model null ist.- Sie können diese auf
AsyncImageoder auf derImageRequestfestlegen. - Mit
SubcomposeAsyncImagekönnen Sie für jeden Zustand echte Composables (Spinner, Shimmer) bereitstellen. rememberAsyncImagePainterstellt den unverarbeitetenstatefür vollständige Kontrolle bereit.- Verwenden Sie einen
listenerder Anfrage, um Ladeergebnisse zu protokollieren oder darauf zu reagieren.
Als Nächstes: Caching und Performance, damit Bilder beim zweiten Mal sofort geladen werden.
Lerne Kotlin mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 36
- Lektionen
- 152
Häufig gestellte Fragen
Ist die Lektion „Platzhalter und Fehlerzustände“ kostenlos?
Ja — der vollständige Text von „Platzhalter und Fehlerzustände“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Android Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Android Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Platzhalter und Fehlerzustände“?
Lade- und Fehlerzustände elegant behandeln Du übst Android Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Android Academy zu starten?
Keine Vorkenntnisse erforderlich. Android Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Platzhalter und Fehlerzustände“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Android Academy-Lektion Code schreiben und ausführen?
Ja. Jede Android Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Bilder mit Coil laden
- Platzhalter und Fehlerzustände
- Caching und Performance
- Audio und Video abspielen