cached_network_image

キャッシュライブラリFlutterDartネットワーク画像UIキャッシュプレースホルダー

キャッシュライブラリ

cached_network_image

概要

cached_network_imageは、Flutterアプリケーション向けのネットワーク画像キャッシュライブラリで、インターネットから画像を読み込み、ローカルキャッシュに保存して高速表示を実現します。

詳細

cached_network_imageは、Flutterエコシステムで最も人気のあるネットワーク画像キャッシュライブラリの一つです。flutter_cache_managerを内部で使用してファイルのダウンロードとキャッシュを管理し、一度ダウンロードした画像をローカルに保存することで、同じ画像への再アクセス時の高速表示を可能にします。プレースホルダーとエラーウィジェットをサポートし、画像読み込み中とエラー時の優雅なユーザー体験を提供します。CachedNetworkImageウィジェットを直接使用するか、CachedNetworkImageProviderを通じてImageウィジェットと組み合わせて使用できます。データ使用量の削減、画像読み込み速度の向上、オフライン環境での画像表示が主な利点です。Web環境では現在のところキャッシュ機能に制限があるものの、モバイルプラットフォーム(iOS/Android)では非常に効果的です。

メリット・デメリット

メリット

  • ローカルキャッシュ: 一度読み込んだ画像を高速再表示
  • データ使用量削減: 同じ画像の重複ダウンロードを防止
  • ユーザー体験向上: プレースホルダーとエラーハンドリングで滑らかな表示
  • 簡単統合: Flutter標準のImageウィジェットと同様のAPI
  • カスタマイズ可能: 柔軟な設定オプションとコールバック
  • オフライン対応: キャッシュされた画像はオフラインでも表示可能
  • メモリ効率: 適切なメモリ管理で大量画像にも対応

デメリット

  • Web制限: Web環境でのキャッシュサポートが限定的
  • 依存関係: 外部パッケージ(flutter_cache_manager)への依存
  • 初期読み込み: 初回アクセス時は通常のネットワーク遅延が発生
  • ストレージ使用: ローカルストレージ容量を消費
  • キャッシュ管理: 手動でのキャッシュクリア機能が必要な場合がある
  • パフォーマンス: 大量の画像キャッシュ時にはパフォーマンス影響の可能性

主要リンク

書き方の例

基本的な使用方法

import 'package:cached_network_image/cached_network_image.dart';

// 基本的なキャッシュ付きネットワーク画像
CachedNetworkImage(
  imageUrl: "https://example.com/image.jpg",
  placeholder: (context, url) => CircularProgressIndicator(),
  errorWidget: (context, url, error) => Icon(Icons.error),
)

プレースホルダーとエラーハンドリング

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,
    ),
  ),
)

進捗表示付きダウンロード

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

カスタムImageProvider使用

import 'package:cached_network_image/cached_network_image.dart';

// Imageウィジェットと組み合わせ
Image(
  image: CachedNetworkImageProvider(
    "https://example.com/image.jpg",
  ),
  fit: BoxFit.cover,
)

// CircleAvatarと組み合わせ
CircleAvatar(
  radius: 30,
  backgroundImage: CachedNetworkImageProvider(
    "https://example.com/avatar.jpg",
  ),
)

リストビューでの使用

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),
            ),
          ),
        );
      },
    );
  }
}

ヒーロー画像とフェードイン効果

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("読み込み中..."),
        ],
      ),
    ),
  ),
)

キャッシュ管理機能

import 'package:flutter_cache_manager/flutter_cache_manager.dart';

class ImageCacheService {
  // キャッシュサイズを確認
  static Future<int> getCacheSize() async {
    final cacheManager = DefaultCacheManager();
    final cacheDirectory = await cacheManager.getTemporaryDirectory();
    // キャッシュサイズ計算ロジック
    return 0; // 実際の実装では適切な計算を行う
  }
  
  // 特定画像のキャッシュを削除
  static Future<void> removeFromCache(String url) async {
    await CachedNetworkImage.evictFromCache(url);
  }
  
  // 全キャッシュをクリア
  static Future<void> clearAllCache() async {
    final cacheManager = DefaultCacheManager();
    await cacheManager.emptyCache();
  }
  
  // キャッシュされた画像一覧を取得
  static Future<List<String>> getCachedImages() async {
    final cacheManager = DefaultCacheManager();
    // 実装はプロジェクトの要件により異なる
    return [];
  }
}

// 使用例
class CacheManagementScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("キャッシュ管理")),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: () => ImageCacheService.clearAllCache(),
            child: Text("全キャッシュをクリア"),
          ),
          ElevatedButton(
            onPressed: () => ImageCacheService.removeFromCache(
              "https://example.com/specific-image.jpg"
            ),
            child: Text("特定画像を削除"),
          ),
        ],
      ),
    );
  }
}