Android Academy · Lektion

Indlæsning af billeder med Coil

Asynkron billedindlæsning i Compose.

Lektion 1 af 413 trin

Indlæsning af billeder med Coil er en gratis Android Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Android Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Android Academy-kurset indeholder 4 lektioner i alt.

Derfor har du brug for en billedindlæser

De fleste moderne apps viser billeder fra internettet: profilfotos, produktbilleder og miniaturebilleder af artikler. Det er sværere, end det ser ud, at downloade og afkode disse billeder korrekt.

Du skal hente bytes over netværket på en baggrundstråd, afkode dem til en bitmap, cache dem, så du ikke henter dem igen, og annullere anmodningen, hvis brugeren ruller væk. Det er fejlbehæftet at gøre dette manuelt.

Coil (Coroutine Image Loader) håndterer alt dette for dig med en lille, Compose-venlig API. I denne lektion indlæser du dit første fjernbillede.

Tilføj Coil til dit projekt

Coil leveres som en Gradle-afhængighed. Til Jetpack Compose skal du bruge artefaktet coil-compose, som giver dig den composable AsyncImage.

Føj det til dit moduls build.gradle.kts. Coil 3 er den aktuelle hovedversion og fungerer på tværs af platforme; det er Compose-integrationen, vi bruger her.

// build.gradle.kts (module level)
dependencies {
    implementation("io.coil-kt.coil3:coil-compose:3.0.4")
    implementation("io.coil-kt.coil3:coil-network-okhttp:3.0.4")
}

Internet-tilladelse

Hvis din app skal downloade billeder fra en URL, skal den have tilladelsen INTERNET. Det er en normal tilladelse, der gives ved installation, så du skal kun erklære den i manifestet. Der vises ingen kørselstidsprompt.

Uden den mislykkes alle netværksanmodninger med en sikkerhedsundtagelse.

<!-- AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.INTERNET" />
    <application ...>
        ...
    </application>
</manifest>

Din første AsyncImage

Den enkleste måde at vise et fjernbillede i Compose på er AsyncImage. Giv den en model (normalt en URL-streng) og en contentDescription, så klarer Coil resten: hentning i baggrunden, afkodning og visning.

Den bruger automatisk coroutines, der er knyttet til kompositionen, så anmodningen annulleres, hvis den composable forlader skærmen.

import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage

@Composable
fun Avatar() {
    AsyncImage(
        model = "https://example.com/avatar.png",
        contentDescription = "User avatar",
        modifier = Modifier.size(96.dp)
    )
}

contentScale: Sådan tilpasses billedet

Billeder har sjældent præcis samme størrelse som den plads, layoutet stiller til rådighed. ContentScale styrer, hvordan bitmappen skaleres inden for sine grænser.

  • ContentScale.Crop fylder feltet og beskærer det, der rager ud (godt til avatarer og miniaturebilleder).
  • ContentScale.Fit holder hele billedet synligt, men kan efterlade tom plads.
  • ContentScale.FillBounds strækker billedet, så feltet fyldes (det kan forvrænge billedet).

Crop er det mest almindelige valg til felter med fast størrelse.

import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage

@Composable
fun CircleAvatar(url: String) {
    AsyncImage(
        model = url,
        contentDescription = "Avatar",
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(80.dp)
            .clip(CircleShape)
    )
}

Opret en anmodning med ImageRequest

Det er den hurtige løsning at sende en URL-streng. Hvis du vil have mere kontrol, kan du oprette en ImageRequest. Så kan du angive indstillinger som crossfade, headere, transformationer og cache-nøgler.

Du skal bruge en Context, som Compose leverer via LocalContext.current.

import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade

@Composable
fun ProductImage(url: String) {
    val context = LocalContext.current
    val request = ImageRequest.Builder(context)
        .data(url)
        .crossfade(true)
        .build()

    AsyncImage(
        model = request,
        contentDescription = "Product photo"
    )
}

Crossfade giver jævn indlæsning

Som standard vises et billede øjeblikkeligt, når det er færdigindlæst, hvilket kan virke brat. crossfade(true) fader billedet ind over en kort animation.

Du kan også angive en varighed i millisekunder for en langsommere eller hurtigere indfading. Denne lille detalje får lister til at virke langt mere gennemarbejdede.

import coil3.request.ImageRequest
import coil3.request.crossfade
import android.content.Context

fun smoothRequest(context: Context, url: String) =
    ImageRequest.Builder(context)
        .data(url)
        .crossfade(durationMillis = 300)
        .build()

Indlæsning fra forskellige kilder

model i AsyncImage er fleksibel. Coil kan indlæse mange kildetyper, ikke kun fjern-URL'er:

  • En String eller Uri til netværks- eller lokale filer.
  • Et id for en drawable-ressource (R.drawable.logo).
  • En File fra enheden.
  • En indholds-Uri fra fotovælgeren.

Det betyder, at den samme composable håndterer fjernbilleder og lokale billeder problemfrit.

import android.net.Uri
import androidx.compose.runtime.Composable
import coil3.compose.AsyncImage

@Composable
fun FlexibleImage(source: Any) {
    // source can be a URL String, a Uri, a File, or a resource id
    AsyncImage(
        model = source,
        contentDescription = null
    )
}

// Examples:
// FlexibleImage("https://example.com/pic.jpg")
// FlexibleImage(Uri.parse("content://media/external/images/1"))

Reagér på indlæsningstilstanden

Nogle gange vil du vide, om billedet indlæses, blev indlæst eller mislykkedes, så du kan vise forskellig brugergrænseflade. AsyncImagePainter viser denne tilstand, men den enkleste tilgang er SubcomposeAsyncImage, som lader dig angive indhold for hver tilstand.

Vi går mere i dybden med pladsholdere i næste lektion; her ser du grundformen for tilstandsafhængig indlæsning.

import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.runtime.Composable
import coil3.compose.SubcomposeAsyncImage

@Composable
fun StatefulImage(url: String) {
    SubcomposeAsyncImage(
        model = url,
        contentDescription = "Photo",
        loading = { CircularProgressIndicator() }
    )
}

Annullering sker automatisk

En af Coils største fordele er automatisk annullering. Fordi AsyncImage starter sin anmodning inde i kompositionen, annulleres den igangværende anmodning, når den composable forlader skærmen (f.eks. når en række ruller ud af en LazyColumn).

Det sparer båndbredde og CPU og forhindrer spildt arbejde. Du skriver ikke selv kode til annullering, og derfor skalerer Coil så godt i lange lister.

import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage

@Composable
fun PhotoFeed(urls: List<String>) {
    LazyColumn {
        items(urls) { url ->
            AsyncImage(
                model = url,
                contentDescription = null,
                modifier = Modifier
                    .fillMaxWidth()
                    .height(200.dp)
            )
        }
    }
}

Et komplet billedkort

Lad os samle det, vi har lært: et kort med et fjernbillede, der fylder toppen, bruger crossfade og beskæres til en fast højde. Det er det grundlæggende mønster, du kommer til at genbruge hele tiden.

import androidx.compose.foundation.layout.*
import androidx.compose.material3.Card
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.unit.dp
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade

@Composable
fun ImageCard(title: String, imageUrl: String) {
    val context = LocalContext.current
    Card(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
        Column {
            AsyncImage(
                model = ImageRequest.Builder(context)
                    .data(imageUrl)
                    .crossfade(true)
                    .build(),
                contentDescription = title,
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxWidth().height(180.dp)
            )
            Text(text = title, modifier = Modifier.padding(16.dp))
        }
    }
}

Hurtig kontrol

Hvilken composable fra coil-compose er den enkleste måde at vise et fjernbillede fra en URL i Jetpack Compose på?

Opsummering

Du har indlæst dine første fjernbilleder med Coil. Vigtigste pointer:

  • Tilføj coil-compose og en OkHttp-netværksafhængighed samt tilladelsen INTERNET.
  • AsyncImage(model = url, contentDescription = ...) er den hurtige løsning.
  • Brug ContentScale.Crop med en fast størrelse til avatarer og miniaturebilleder.
  • Opret en ImageRequest for crossfade og mere kontrol.
  • Coil annullerer automatisk igangværende anmodninger, når composables forlader skærmen.

Næste trin: gør indlæsningen elegant med pladsholdere og fejltilstande.

Gratis at komme i gang

Lær Kotlin med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
36
Lektioner
152

Ofte stillede spørgsmål

Er lektionen “Indlæsning af billeder med Coil” gratis?

Ja — alle 3 lektioner i læringssporet Android Academy, inklusive “Indlæsning af billeder med Coil”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Android Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Indlæsning af billeder med Coil”?

Asynkron billedindlæsning i Compose. Du øver dig i Android Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Android Academy?

Der kræves ingen tidligere erfaring. Android Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Indlæsning af billeder med Coil”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Android Academy-lektion?

Ja. Alle Android Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Indlæsning af billeder med Coil
  2. Pladsholdere og fejltilstande
  3. Caching og ydeevne
  4. Afspilning af lyd og video
← Tilbage til Android Academy