cached_network_image

Cache LibraryFlutterDartNetwork ImagesUI CachePlaceholder

Cache Library

cached_network_image

Overview

cached_network_image is a network image caching library for Flutter applications that loads images from the internet and stores them in local cache for fast display.

Details

cached_network_image is one of the most popular network image caching libraries in the Flutter ecosystem. It uses flutter_cache_manager internally to manage file downloads and caching, storing downloaded images locally to enable fast display on subsequent access to the same images. It supports placeholders and error widgets, providing a graceful user experience during image loading and error states. It can be used directly with the CachedNetworkImage widget or combined with Image widgets through CachedNetworkImageProvider. The main benefits include reduced data usage, improved image loading speed, and offline image display capability. While it currently has limited caching functionality on web platforms, it is very effective on mobile platforms (iOS/Android).

Advantages and Disadvantages

Advantages

  • Local Caching: Fast re-display of once-loaded images
  • Reduced Data Usage: Prevents duplicate downloads of the same images
  • Enhanced User Experience: Smooth display with placeholders and error handling
  • Easy Integration: Similar API to Flutter's standard Image widget
  • Customizable: Flexible configuration options and callbacks
  • Offline Support: Cached images can be displayed offline
  • Memory Efficient: Proper memory management for handling large numbers of images

Disadvantages

  • Web Limitations: Limited caching support in web environments
  • Dependencies: Dependency on external packages (flutter_cache_manager)
  • Initial Loading: Network latency occurs on first access
  • Storage Usage: Consumes local storage capacity
  • Cache Management: Manual cache clearing functionality may be required
  • Performance: Potential performance impact when caching large numbers of images

Key Links

Code Examples

Basic Usage

import 'package:cached_network_image/cached_network_image.dart';

// Basic cached network image
CachedNetworkImage(
  imageUrl: "https://example.com/image.jpg",
  placeholder: (context, url) => CircularProgressIndicator(),
  errorWidget: (context, url, error) => Icon(Icons.error),
)

Placeholder and Error Handling

CachedNetworkImage(
  imageUrl: "https://example.com/profile.jpg",
  imageBuilder: (context, imageProvider) => Container(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: imageProvider,
        fit: BoxFit.cover,
      ),
    ),
  ),
  placeholder: (context, url) => Container(
    color: Colors.grey[300],
    child: Center(
      child: CircularProgressIndicator(),
    ),
  ),
  errorWidget: (context, url, error) => Container(
    color: Colors.grey[300],
    child: Icon(
      Icons.error,
      color: Colors.red,
      size: 50,
    ),
  ),
)

Download with Progress Indicator

CachedNetworkImage(
  imageUrl: "https://example.com/large-image.jpg",
  progressIndicatorBuilder: (context, url, downloadProgress) => 
    CircularProgressIndicator(
      value: downloadProgress.progress,
    ),
  errorWidget: (context, url, error) => Icon(Icons.error),
)

Using Custom ImageProvider

import 'package:cached_network_image/cached_network_image.dart';

// Combined with Image widget
Image(
  image: CachedNetworkImageProvider(
    "https://example.com/image.jpg",
  ),
  fit: BoxFit.cover,
)

// Combined with CircleAvatar
CircleAvatar(
  radius: 30,
  backgroundImage: CachedNetworkImageProvider(
    "https://example.com/avatar.jpg",
  ),
)

Usage in ListView

class ImageList extends StatelessWidget {
  final List<String> imageUrls;
  
  const ImageList({Key? key, required this.imageUrls}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: imageUrls.length,
      itemBuilder: (context, index) {
        return Card(
          child: CachedNetworkImage(
            imageUrl: imageUrls[index],
            height: 200,
            fit: BoxFit.cover,
            placeholder: (context, url) => Container(
              height: 200,
              color: Colors.grey[300],
              child: Center(child: CircularProgressIndicator()),
            ),
            errorWidget: (context, url, error) => Container(
              height: 200,
              color: Colors.grey[300],
              child: Icon(Icons.error),
            ),
          ),
        );
      },
    );
  }
}

Hero Image with Fade Effects

CachedNetworkImage(
  imageUrl: "https://example.com/hero-image.jpg",
  fadeInDuration: Duration(milliseconds: 500),
  fadeOutDuration: Duration(milliseconds: 300),
  placeholder: (context, url) => Container(
    height: 200,
    color: Colors.grey[300],
    child: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          CircularProgressIndicator(),
          SizedBox(height: 10),
          Text("Loading..."),
        ],
      ),
    ),
  ),
)

Cache Management Features

import 'package:flutter_cache_manager/flutter_cache_manager.dart';

class ImageCacheService {
  // Check cache size
  static Future<int> getCacheSize() async {
    final cacheManager = DefaultCacheManager();
    final cacheDirectory = await cacheManager.getTemporaryDirectory();
    // Cache size calculation logic
    return 0; // Actual implementation should perform proper calculation
  }
  
  // Remove specific image from cache
  static Future<void> removeFromCache(String url) async {
    await CachedNetworkImage.evictFromCache(url);
  }
  
  // Clear all cache
  static Future<void> clearAllCache() async {
    final cacheManager = DefaultCacheManager();
    await cacheManager.emptyCache();
  }
  
  // Get list of cached images
  static Future<List<String>> getCachedImages() async {
    final cacheManager = DefaultCacheManager();
    // Implementation varies based on project requirements
    return [];
  }
}

// Usage example
class CacheManagementScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Cache Management")),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: () => ImageCacheService.clearAllCache(),
            child: Text("Clear All Cache"),
          ),
          ElevatedButton(
            onPressed: () => ImageCacheService.removeFromCache(
              "https://example.com/specific-image.jpg"
            ),
            child: Text("Remove Specific Image"),
          ),
        ],
      ),
    );
  }
}