Knižnica Coil slúži na načítanie obrázkov z internetu a ich zobrazenie v JetPack Compose aplikácii. Načítavanie obrázkov z internetu má isté zákutia, ktoré Coil rieši ako napríklad:
Potrebuješ tieto závislosti:
dependencies {
implementation("io.coil-kt.coil3:coil-compose:3.6.1")
implementation("io.coil-kt.coil3:coil-network-okhttp:3.6.1") // Android only
}
a happy flow spôsob pre načítanie obrázku z internetu je:
AsyncImage(
model = "https://example.com/image.jpg",
contentDescription = null,
)
V Kotlin Multiplaform potrebuješ namiesto OkHttp použiť Ktor. Pozri si tento návod.
Ak chceš nastaviť správanie všetkých, z internetu načítaných, obrázkov, potrebuješ globálnu konfiguráciu Coil. Tu je
ideálne použiť vlastnú Application triedu, ktorá bude implementovať rozhranie SingletonImageLoader.Factory.
Application triedyMainActivity triedu pridaj novú Kotlin triedu s názvom <App>Application (App nahraď krátkym názvom svojej aplikácie.).<App>Application nech rozširuje triedu ApplicationAndroidManifest.xml nastav svoju <App>Application triedu ako android:name atribút v elemente <application>// SsndDemoApplication.kt
import android.app.Application
class SsndDemoApplication : Application() {
}
<!-- AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:name=".SsndDemoApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
...
SingletonImageLoader.FactoryV globálnej konfigurácii sa toho dá nastaviť kopec. Zvykneme tu nastavovať prácu s disk/memory cache pre rýchlejšie znovunačítanie obrázkov a podobne. My sa teraz venujme iba obrázkom, ktoré sa zobrazia v prípade chýb (hoci toto nie je štandardný use-case):
placeholder - obrázok, ktorý sa zobrazí, keď sa obrázok načítavaerror - obrázok, ktorý sa zobrazí, keď sa obrázok nepodarilo načítaťfallback - obrázok, ktorý sa zobrazí, keď je načítavaný obrázok prázdny (null)class SsndDemoApplication : Application(), SingletonImageLoader.Factory {
override fun newImageLoader(context: Context): ImageLoader {
return ImageLoader.Builder(context)
.crossfade(true)
.placeholder(getDrawable(R.drawable.ic_image_loading)?.asImage())
.error(getDrawable(R.drawable.ic_image_error)?.asImage())
.fallback(getDrawable(R.drawable.ic_image_fallback)?.asImage())
.build()
}
}
Ak chceš namiesto statickej ikony v prípade loadingu zobraziť vlastný komponent, AsyncImage ti nepomôže. Môžeš použiť
rememberAsyncImagePainter, ktorý ti umožňuje získať stav aktuálne načítavaného obrázka. Zápis je pomerne zložitý,
preto je vhodné vytvoriť si vlastnú Composable funkciu, ktorá toto správanie zakryje.
val sizeResolver = rememberConstraintsSizeResolver()
val painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalPlatformContext.current)
.data("https://example.com/image.jpg")
.size(sizeResolver)
.build()
)
val painterState by painter.state.collectAsState()
when(painterState) {
is AsyncImagePainter.State.Loading -> Text("Loading...")
is AsyncImagePainter.State.Success -> Image(painter = painter, contentDescription = null)
is AsyncImagePainter.State.Error -> Text("Error")
else -> Text("Unknown")
}
Predvolene sa každé HTTP volanie pre získanie obrázkov volá ako štandardný HTTP GET request na danú url. Ak chceme
upraviť metódu alebo hlavičky, môžeme tak spraviť cez ImageRequest.Builder nasledovne:
val request = ImageRequest.Builder(LocalContext.current)
.data("url")
.httpMethod("POST")
.httpBody(
NetworkRequestBody(("{\"user\":\"id\"}".toByteArray().toByteString()))
)
.httpHeaders(NetworkHeaders.Builder()
.add("Authorization", "Bearer TOKEN")
.build())
.build()
// pouzitie v painter
val painter = rememberAsyncImagePainter(request)
// pouzitie v AsyncImage
AsyncImage(model = request, contentDescription = null)