CachedNetworkImage to widget Flutter do ładowania i buforowania obrazów z sieci z obsługą postępu, placeholderów i obsługi błędów. Według oficjalnej strony pakietu, biblioteka opiera się na flutter_cache_manager i zapewnia automatyczne buforowanie na dysku z konfigurowalnym TTL. CachedNetworkImage jest standardowym rozwiązaniem do ładowania obrazów w aplikacjach Flutter z buforowaniem.
Najważniejsze
CachedNetworkImage to widget Flutter z pakietu pub.dev o tej samej nazwie, zapewniający ładowanie obrazów z sieci z automatycznym buforowaniem. Jest nakładką na standardowy Image.network, dodającą buforowanie plikowe, wskaźniki postępu i niestandardową obsługę błędów.
Wewnętrznie CachedNetworkImage używa flutter_cache_manager — menedżera pamięci podręcznej z bazą danych SQLite do śledzenia plików. Przy pierwszym żądaniu obraz jest pobierany z sieci, zapisywany na dysku, a przy kolejnych żądaniach dostarczany z pamięci podręcznej z uwzględnieniem TTL (domyślnie 7 dni). Pamięć podręczna in-memory jest zarządzana przez standardowy ImageCache Flutter.
Pakiet ma ponad 4 000 polubień na pub.dev i jest używany w tysiącach projektów Flutter. CachedNetworkImage obsługuje wszystkie platformy Flutter: Android, iOS, Web, macOS, Windows i Linux. Dzięki jednolitemu API programista otrzymuje wieloplatformowe ładowanie obrazów bez kodu specyficznego dla platformy.
Flutter używa dwupoziomowego systemu buforowania: ImageCache (pamięć) i flutter_cache_manager (dysk + SQLite). ImageCache to globalna pamięć podręczna zdekodowanych obrazów z limitem liczby (domyślnie 1000) i rozmiaru (domyślnie 100 MB). flutter_cache_manager zarządza plikami na dysku i ich metadanymi.
Gdy CachedNetworkImage otrzymuje żądanie obrazu, najpierw sprawdza ImageCache Flutter — jeśli obraz jest już zdekodowany w pamięci, wyświetla się natychmiast. W przypadku braku sprawdzany jest dysk przez flutter_cache_manager: zapytanie SQLite sprawdza, czy plik jest w pamięci podręcznej i czy jego TTL nie wygasł. Jeśli plik jest aktualny — jest odczytywany z dysku, dekodowany i wyświetlany. Jeśli pliku nie ma lub TTL wygasł — wykonywane jest żądanie HTTP.
DefaultCacheManager udostępnia metody emptyCache() (całkowite czyszczenie), cleanCache() (usuwanie tylko nieaktualnych) oraz clearCacheWithAge() z niestandardową datą. ImageCache jest czyszczony automatycznie przy braku pamięci lub ręcznie przez imageCache.clear().
CachedNetworkImage jest zbudowany na kompozycji standardowych widgetów Flutter. Wewnętrzna implementacja używa ImageProvider do asynchronicznego ładowania i StatefulWidget do śledzenia cyklu życia.
imageUrl — obowiązkowy parametr, URL obrazu (String lub Uri). placeholder — widget wyświetlany podczas ładowania. errorWidget — widget przy błędzie ładowania. progressIndicatorBuilder — builder otrzymujący kontekst, URL i DownloadProgress z polami totalSize i downloadedSize.
CachedNetworkImageProvider — implementacja ImageProvider, zwracająca CachedNetworkStreamImage, który zarządza pobieraniem i buforowaniem. Provider integruje się z ImageCache Flutter i obsługuje wszystkie możliwości standardowego ImageProvider: skalowanie, centrowanie i powtarzanie.
flutter_cache_manager — biblioteka leżąca u podstaw buforowania CachedNetworkImage. Udostępnia DefaultCacheManager ze skonfigurowaną bazą SQLite, TTL i limitem plików. W razie potrzeby można utworzyć niestandardowy CacheManager z unikalnymi parametrami.
| Parametr | Opis | Wartość domyślna |
|---|---|---|
| maxAgeCacheObject | Maksymalny czas przechowywania pliku | 7 dni |
| maxNrOfCacheObjects | Maksymalna liczba plików | 200 |
| key | Unikalny identyfikator menedżera | "default" |
| repo | Typ przechowywania metadanych | CacheObjectRepository (SQLite) |
| fileService | Klient HTTP do pobierania | HttpFileService |
Niestandardowy CacheManager tworzy się przez dziedziczenie po CacheManager z nadpisywaniem metod. Jest to przydatne, gdy trzeba przechowywać obrazy w osobnym katalogu lub używać innego klienta HTTP. Następnie instancja menedżera jest przekazywana do parametru cacheManager w CachedNetworkImage.
Baza SQLite DefaultCacheManager znajduje się w katalogu aplikacji temporaryDirectory pod ścieżką `{key}/CacheObjects.db`. Zawiera tabelę cacheObjects z polami key (URL), relativePath, url, creationDate, eTag, httpHeaders. Przy czyszczeniu nieaktualnych rekordów używane jest zapytanie SQL z warunkiem według maxAgeCacheObject.
CachedNetworkImage zapewnia dwa główne sposoby ładowania: widget CachedNetworkImage i provider CachedNetworkImageProvider dla niestandardowych scenariuszy.
CachedNetworkImage — podstawowy sposób. Wystarczy przekazać imageUrl i placeholder. Widget automatycznie wyświetli placeholder do zakończenia ładowania i zastąpi go obrazem.
CachedNetworkImage(
imageUrl: "https://example.com/photo.jpg",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
width: 200,
height: 200,
fit: BoxFit.cover,
)
placeholder i errorWidget to funkcje-builder przyjmujące kontekst, URL i (dla errorWidget) obiekt błędu. Takie podejście pozwala wyświetlać różne zastępki w zależności od URL lub typu błędu.
progressIndicatorBuilder — parametr umożliwiający wyświetlanie postępu ładowania w procentach. DownloadProgress zawiera totalSize (może być -1, jeśli rozmiar jest nieznany) i downloadedSize.
CachedNetworkImage(
imageUrl: "https://example.com/large.jpg",
progressIndicatorBuilder: (context, url, downloadProgress) {
return Center(
child: SizedBox(
width: 50,
height: 50,
child: Stack(
alignment: Alignment.center,
children: [
CircularProgressIndicator(
value: downloadProgress.progress,
),
Text(
"\(downloadProgress.downloadedSize ~/ 1024) KB",
),
],
),
),
};
},
imageBuilder: (context, imageProvider) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
};
},
)
imageBuilder — opcjonalny parametr umożliwiający dostosowanie wyświetlania obrazu: dodanie zaokrąglenia, cienia, dekoracji. W przykładzie użyto DecorationImage z BorderRadius do zaokrąglonych rogów.
CachedNetworkImageProvider — provider dla Image lub DecorationImage bez użycia widgetu CachedNetworkImage. Przydatny przy pracy z BoxDecoration, FadeInImage lub niestandardowymi widgetami Image.
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider(
"https://example.com/bg.jpg",
maxWidthBytes: 2048,
maxHeightBytes: 2048,
),
fit: BoxFit.cover,
),
),
)
Parametr imageBuilder w CachedNetworkImage pozwala zastąpić standardowy widget Image niestandardową implementacją. Zamiast bezpośredniego wyświetlania Image można użyć Container z dekoracją, ClipRRect z przycięciem lub Ink.image dla efektu ripple. imageBuilder otrzymuje kontekst i ImageProvider gotowego obrazu, dając pełną kontrolę nad renderowaniem.
Dodatkowe parametry: memCacheWidth i memCacheHeight ograniczają rozmiar buforowanego obrazu w pamięci RAM, zmniejszając obciążenie ImageCache Flutter. cacheKey pozwala ustawić niestandardowy klucz pamięci podręcznej zamiast URL, co jest przydatne dla obrazów z tokenami autoryzacji w URL (parametry zapytania zmieniają się przy każdym żądaniu, ale zawartość pozostaje taka sama).
Standardowy widget Image.network ładuje obraz przy każdym przebudowie widgetu bez zapisywania na dysku. CachedNetworkImage dodaje buforowanie plikowe, postęp i obsługę błędów, ale dodaje zależność od flutter_cache_manager i SQLite.
| Kryterium | Image.network | CachedNetworkImage |
|---|---|---|
| Pamięć podręczna na dysku | Nie (tylko memory cache Flutter) | Tak (SQLite + pliki) |
| Postęp | Nie | progressIndicatorBuilder |
| Error widget | Tylko czerwony placeholder w debug | Niestandardowy errorWidget |
| TTL pamięci podręcznej | Nie dotyczy | Konfigurowalny (domyślnie 7 dni) |
| Zależności | Nie (wbudowane we Flutter) | cached_network_image + flutter_cache_manager + sqflite |
| Dostęp offline | Nie | Tak (przy wcześniej pobranych plikach) |
| Rozmiar kompilacji | 0 KB dodatkowo | ~300 KB dodatkowo |
Dla projektów, w których ważna jest praca offline i oszczędność transferu, CachedNetworkImage jest jednoznacznym wyborem. Dla prostych pojedynczych ekranów (np. onboarding lub splash) Image.network nie wymaga dodatkowych zależności.
CachedNetworkImage jest dodawany jako standardowa zależność pub.dev. Po instalacji widget jest gotowy do użycia. flutter_cache_manager wchodzi jako zależność tranzytowna.
// pubspec.yaml
dependencies:
flutter:
sdk: flutter
cached_network_image: ^3.4.1
Domyślnie używany jest DefaultCacheManager z ustawieniami: TTL = 7 dni, maks. 200 plików. Aby zmienić globalne parametry, tworzy się niestandardową instancję CacheManager z Config, gdzie nadpisuje się maxAgeCacheObject, maxNrOfCacheObjects i repo.
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
final customCacheManager = CacheManager(
Config(
"custom_images",
stalePeriod: Duration(days: 14),
maxNrOfCacheObjects: 500,
repo: JsonCacheInfoRepository(
databaseName: "custom_images_cache.db",
),
),
);
// Użycie niestandardowego menedżera:
CachedNetworkImage(
cacheManager: customCacheManager,
imageUrl: url,
// ...
)
maxWidthBytes i maxHeightBytes — opcjonalne parametry do ograniczenia rozmiaru buforowanego pliku. Jest to przydatne do oszczędzania miejsca na dysku, gdy oryginalny obraz jest większy niż potrzebny rozmiar ekranu.
Często zadawane pytania
CachedNetworkImage — widget Flutter do ładowania obrazów z sieci z automatycznym buforowaniem na dysku. Służy do oszczędzania transferu, pracy w trybie offline i wyświetlania postępu ładowania, czego brak w standardowym Image.network.
Dodaj cached_network_image: ^3.4.1 w sekcji dependencies pliku pubspec.yaml i wykonaj flutter pub get. Następnie zaimportuj pakiet w pliku: import 'package:cached_network_image/cached_network_image.dart'.
Utwórz niestandardowy CacheManager z Config, gdzie parametr stalePeriod jest ustawiony jako Duration. Przekaż utworzonego menedżera do parametru cacheManager widgetu CachedNetworkImage. Domyślnie pliki są przechowywane przez 7 dni.
Wywołaj DefaultCacheManager().emptyCache() do całkowitego czyszczenia wszystkich plików. Do czyszczenia tylko nieaktualnych użyj cleanCache(). Niestandardowy menedżer jest czyszczony przez wywołanie emptyCache na jego instancji.
Tak, CachedNetworkImage obsługuje Android, iOS, Web, macOS, Windows i Linux. Jednolite API zapewnia takie samo zachowanie na wszystkich platformach, a buforowanie działa przez flutter_cache_manager dostosowany do każdego systemu operacyjnego.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również