visibility_cached_image 0.2.0
visibility_cached_image: ^0.2.0 copied to clipboard
A Flutter package for efficient image loading with in-memory + on-disk caching, visibility-aware lazy loading and a bounded request queue.
visibility_cached_image #
A small image widget built for big lists. Two-tier cache (in-memory + on-disk), bounded concurrent downloads, and only loads when visible — so scrolling past 200 tiles doesn't fire 200 network requests.
- ✅ Network + asset images
- ✅ In-memory LRU cache, bounded by entry count and total bytes
- ✅ Persistent on-disk cache (flat-file, no native deps)
- ✅ Visibility-aware lazy loading via
visibility_detector - ✅ Bounded concurrent downloads (
sequential/random/parallel/unqueued) - ✅ Auto-cancels in-flight downloads when scrolled away or disposed
- ✅ Optional — no
init()required, lazy bootstraps on first use
Install #
dependencies:
visibility_cached_image: ^0.2.0
Quick start #
import 'package:visibility_cached_image/visibility_cached_image.dart';
// In a grid / list:
VisibilityCachedImage.network(
'https://picsum.photos/300/300',
width: 100,
height: 100,
fit: BoxFit.cover,
)
That's it — no init(), no Hive, no boxes. The cache spins itself up on the first request with sensible defaults.
Asset images #
VisibilityCachedImage.asset(
'assets/photo.jpg',
width: 300,
height: 200,
fit: BoxFit.cover,
)
Loading / error builders #
VisibilityCachedImage.network(
url,
loadingBuilder: (context, progress) =>
Center(child: CircularProgressIndicator(value: progress)),
errorBuilder: (context, error, stack) =>
const Center(child: Icon(Icons.broken_image_outlined)),
)
progress is a value between 0.0 and 1.0 based on the Content-Length-aware Dio download progress. It's clamped to ≥2% deltas to avoid setState storms.
Hero transitions #
VisibilityCachedImage.network(url, heroTag: 'photo-$id')
Disable visibility (load eagerly) #
By default the widget waits until it's on-screen. Use disableVisibility: true for above-the-fold content where you want to start loading immediately.
VisibilityCachedImage.network(url, disableVisibility: true)
Visibility threshold #
Trigger loading only when more than 30% of the widget is visible:
VisibilityCachedImage.network(url, visibilityThreshold: 0.3)
Configuration #
Calling init() is optional. Use it when you want to tune things:
await VisibilityCacheImageConfig.init(
maxMemoryEntries: 256,
maxMemoryBytes: 96 * 1024 * 1024, // 96 MiB
maxConcurrentRequests: 6,
maxAge: const Duration(days: 14),
loadingType: LoadingType.sequential,
dioInstance: myAuthenticatedDio,
subDir: 'product_thumbs', // optional: isolate this app feature's cache
);
Cache controls #
// Has a URL been cached on disk?
await VisibilityCacheImageConfig.hasCachedImage(url);
// Delete a single entry
await VisibilityCacheImageConfig.deleteCachedImage(url);
// Wipe everything
await VisibilityCacheImageConfig.clearAllCachedImages();
// Just drop the in-memory tier
VisibilityCacheImageConfig.clearMemoryCache();
// Inspect
VisibilityCacheImageConfig.memoryCacheLength; // # of entries
VisibilityCacheImageConfig.memoryCacheSize; // bytes
await VisibilityCacheImageConfig.diskCacheSize(); // bytes
Queue control #
Need to pause downloads (e.g. behind a "low data mode" toggle)?
VisibilityCacheImageConfig.requestQueue.isStopped = true;
// ...
VisibilityCacheImageConfig.requestQueue.isStopped = false;
VisibilityCacheImageConfig.requestQueue.cancelPending(); // drop still-pending tasks
VisibilityCacheImageConfig.requestQueue.maxConcurrent = 8;
Loading strategies #
LoadingType |
What it does |
|---|---|
sequential (default) |
FIFO. Strict order. |
random |
Pick a random pending task at each tick. |
parallel |
Pop up to maxConcurrent tasks and run them all. |
unqueued |
Bypass the queue — start every task immediately. |
Platform support #
Pure-Dart Flutter package — works on Android, iOS, macOS, Windows, Linux. (Web is not supported because the disk cache uses dart:io.)
Support #
If this package helped, consider supporting the author: