Wczytywanie obrazów za pomocą Coil
Asynchroniczne wczytywanie obrazów w Compose
Wczytywanie obrazów za pomocą Coil to bezpłatna lekcja Android Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Android Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Android Academy zawiera 4 lekcji w sumie.
Dlaczego potrzebujesz loadera obrazów
Większość nowoczesnych aplikacji wyświetla obrazy z internetu: zdjęcia profilowe, zdjęcia produktów i miniatury artykułów. Prawidłowe pobieranie i dekodowanie tych obrazów jest trudniejsze, niż mogłoby się wydawać.
Należy pobrać bajty przez sieć w wątku działającym w tle, zdekodować je do bitmapy, zapisać w pamięci podręcznej, aby nie pobierać ich ponownie, oraz anulować żądanie, gdy użytkownik przewinie obraz poza ekran. Ręczne wykonanie tych czynności łatwo prowadzi do błędów.
Coil (Coroutine Image Loader) wykonuje to wszystko za Ciebie, udostępniając niewielkie API przyjazne Compose. W tej lekcji załadujesz swój pierwszy zdalny obraz.
Dodawanie Coil do projektu
Coil jest dostarczany jako zależność Gradle. W przypadku Jetpack Compose potrzebny jest artefakt coil-compose, który udostępnia composable AsyncImage.
Dodaj go do pliku build.gradle.kts modułu. Coil 3 to obecna główna wersja, działająca na wielu platformach; w tym miejscu korzystamy z integracji z Compose.
// 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")
}Uprawnienie do internetu
Aby pobierać obrazy z adresu URL, aplikacja potrzebuje uprawnienia INTERNET. Jest to zwykłe uprawnienie przyznawane podczas instalacji, dlatego wystarczy zadeklarować je w manifeście. Nie pojawi się żadne żądanie w czasie działania aplikacji.
Bez tego każde żądanie sieciowe kończy się wyjątkiem bezpieczeństwa.
<!-- AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application ...>
...
</application>
</manifest>Pierwszy AsyncImage
Najprostszym sposobem wyświetlenia zdalnego obrazu w Compose jest użycie AsyncImage. Przekaż mu model (zwykle jest to tekst zawierający adres URL) oraz contentDescription, a Coil zajmie się resztą: pobraniem w tle, dekodowaniem i wyświetleniem.
Automatycznie korzysta on z korutyn powiązanych z kompozycją, więc żądanie zostanie anulowane, gdy composable opuści ekran.
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: dopasowanie obrazu
Obrazy rzadko mają dokładnie taki rozmiar jak przeznaczone dla nich miejsce w układzie. ContentScale określa sposób skalowania bitmapy wewnątrz jej granic.
ContentScale.Cropwypełnia pole i przycina wystającą część (świetnie sprawdza się w przypadku awatarów i miniatur).ContentScale.Fitzachowuje cały obraz, ale może pozostawić puste miejsce.ContentScale.FillBoundsrozciąga obraz, aby wypełnić pole (może powodować zniekształcenia).
Crop jest najczęstszym wyborem dla pól o stałym rozmiarze.
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)
)
}Budowanie żądania za pomocą ImageRequest
Przekazanie tekstu zawierającego adres URL to szybkie rozwiązanie. Aby uzyskać większą kontrolę, zbuduj obiekt ImageRequest. Umożliwia on ustawienie takich opcji jak crossfade, nagłówki, transformacje i klucze pamięci podręcznej.
Potrzebujesz obiektu Context, który Compose udostępnia za pośrednictwem 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 zapewniający płynne ładowanie
Domyślnie obraz pojawia się natychmiast po zakończeniu ładowania, co może wyglądać gwałtownie. crossfade(true) powoduje płynne pojawienie się obrazu w krótkiej animacji.
Możesz również przekazać czas trwania w milisekundach, aby spowolnić lub przyspieszyć przenikanie. Ten drobny zabieg sprawia, że listy wyglądają znacznie bardziej dopracowanie.
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()Ładowanie z różnych źródeł
Wartość model w AsyncImage jest elastyczna. Coil może ładować obrazy z wielu rodzajów źródeł, nie tylko ze zdalnych adresów URL:
StringlubUridla plików sieciowych albo lokalnych.- Id zasobu drawable (
R.drawable.logo). - Obiekt
Filez urządzenia. - Treściowy obiekt
Uriz selektora zdjęć.
Oznacza to, że ten sam composable bezproblemowo obsługuje obrazy zdalne i lokalne.
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"))Reagowanie na stan ładowania
Czasami trzeba wiedzieć, czy obraz jest ładowany, został pomyślnie załadowany czy wystąpił błąd, aby wyświetlić odpowiedni interfejs. AsyncImagePainter udostępnia ten stan, ale najprostszym rozwiązaniem jest SubcomposeAsyncImage, który pozwala określić zawartość dla każdego stanu.
W następnej lekcji dokładniej omówimy elementy zastępcze; tutaj przedstawiamy strukturę ładowania zależnego od stanu.
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() }
)
}Anulowanie bez dodatkowej pracy
Jedną z największych zalet Coil jest automatyczne anulowanie. Ponieważ AsyncImage uruchamia żądanie w obrębie kompozycji, gdy composable opuszcza ekran (na przykład wiersz zostaje przewinięty poza LazyColumn), trwające żądanie jest anulowane.
Oszczędza to transfer i czas procesora oraz zapobiega wykonywaniu niepotrzebnej pracy. Nie trzeba samodzielnie pisać kodu anulowania, dlatego Coil tak dobrze skaluje się w długich listach.
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)
)
}
}
}Kompletna karta obrazu
Połączmy zdobytą wiedzę: utwórzmy kartę ze zdalnym obrazem, który wypełnia górną część, pojawia się z efektem crossfade i jest przycinany do stałej wysokości. To podstawowy wzorzec, który będzie często używany ponownie.
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))
}
}
}Szybkie sprawdzenie
Który composable z coil-compose jest najprostszym sposobem wyświetlenia zdalnego obrazu na podstawie adresu URL w Jetpack Compose?
Podsumowanie
Załadowałeś swoje pierwsze zdalne obrazy za pomocą Coil. Najważniejsze informacje:
- Dodaj
coil-composei zależność sieciową OkHttp, a także uprawnienieINTERNET. AsyncImage(model = url, contentDescription = ...)to szybkie rozwiązanie.- Używaj
ContentScale.Cropze stałym rozmiarem w przypadku awatarów i miniatur. - Zbuduj
ImageRequest, aby użyć crossfade i uzyskać większą kontrolę. - Coil automatycznie anuluje trwające żądania, gdy composable opuszczą ekran.
Następnie: płynne ładowanie za pomocą elementów zastępczych i stanów błędu.
Często zadawane pytania
Czy lekcja „Wczytywanie obrazów za pomocą Coil” jest bezpłatna?
Tak — pełny tekst „Wczytywanie obrazów za pomocą Coil” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Android Academy, przejdź na CoddyKit PRO. Kurs Android Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Wczytywanie obrazów za pomocą Coil”?
Asynchroniczne wczytywanie obrazów w Compose Ćwiczysz Android Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Android Academy?
Nie wymagamy żadnego doświadczenia. Android Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Wczytywanie obrazów za pomocą Coil”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Android Academy?
Tak. Każda lekcja Android Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Wczytywanie obrazów za pomocą Coil
- Elementy zastępcze i stany błędów
- Buforowanie i wydajność
- Odtwarzanie dźwięku i obrazu