Skip to content

源码:labs/flutter/host/lib/topics/image_loading/cached_network_image_demo_page.dart ​

  • 原始路径:labs/flutter/host/lib/topics/image_loading/cached_network_image_demo_page.dart
  • 类型:dart
dart
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';

/// Flutter 图片加载演示:对应 docs/11-image-loading/04-flutter-image-loading.md
///
/// 覆盖:
/// - CachedNetworkImage 网络图 + 占位 / 进度 / 失败回调
/// - memCacheWidth 解码降采样(等价于 Android inBitmap / inSampleSize)
/// - 缓存清理:ImageCache(内存)与 CachedNetworkImage(磁盘)两层
class CachedNetworkImageDemoPage extends StatefulWidget {
  const CachedNetworkImageDemoPage({super.key});

  static const routeName = '/image_loading';

  @override
  State<CachedNetworkImageDemoPage> createState() =>
      _CachedNetworkImageDemoPageState();
}

class _CachedNetworkImageDemoPageState
    extends State<CachedNetworkImageDemoPage> {
  static const _url =
      'https://picsum.photos/seed/flutter_image_lab/800/600';

  String _status = '等待操作';

  void _clearMemoryCache() {
    imageCache.clear();
    imageCache.clearLiveImages();
    setState(() => _status = '已清空 ImageCache(内存)');
  }

  Future<void> _clearDiskCache() async {
    await CachedNetworkImage.evictFromCache(_url);
    // async gap 后先检查 mounted,避免页面已销毁时调用 setState 报错
    if (!mounted) return;
    setState(() => _status = '已驱逐磁盘缓存(下次需重新下载)');
  }

  @override
  Widget build(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter 图片加载')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          const Text(
            'CachedNetworkImage:网络图 + 占位 / 进度 / 失败 + 磁盘缓存',
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 12),
          ClipRRect(
            borderRadius: BorderRadius.circular(12),
            child: CachedNetworkImage(
              imageUrl: _url,
              fit: BoxFit.cover,
              placeholder: (context, url) => const SizedBox(
                height: 200,
                child: Center(child: CircularProgressIndicator()),
              ),
              errorWidget: (context, url, error) =>
                  const Icon(Icons.error, size: 48),
              fadeInDuration: const Duration(milliseconds: 300),
              memCacheWidth: 800,
            ),
          ),
          const SizedBox(height: 16),
          const Text(
            '解码降采样(memCacheWidth = 200):内存随面积下降',
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 12),
          ClipRRect(
            borderRadius: BorderRadius.circular(12),
            child: CachedNetworkImage(
              imageUrl: _url,
              memCacheWidth: 200,
              fit: BoxFit.cover,
              placeholder: (context, url) => const SizedBox(
                height: 120,
                child: Center(child: CircularProgressIndicator()),
              ),
              errorWidget: (context, url, error) => const Icon(Icons.error),
            ),
          ),
          const SizedBox(height: 16),
          Text(
            '状态:$_status',
            style: TextStyle(color: colorScheme.onSurfaceVariant),
          ),
          const SizedBox(height: 12),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              FilledButton.icon(
                onPressed: _clearMemoryCache,
                icon: const Icon(Icons.memory),
                label: const Text('清内存缓存 (ImageCache)'),
              ),
              OutlinedButton.icon(
                onPressed: _clearDiskCache,
                icon: const Icon(Icons.storage),
                label: const Text('清磁盘缓存 (CachedNetworkImage)'),
              ),
            ],
          ),
          const SizedBox(height: 12),
          const Text(
            '要点:ImageCache 是 Dart 侧内存 LRU(数量 + 字节双限);'
            'CachedNetworkImage 额外提供设备磁盘缓存。两者是两层,'
            '清内存不代表清磁盘。超大图务必设 memCacheWidth / cacheWidth 降采样。',
            style: TextStyle(fontSize: 13),
          ),
        ],
      ),
    );
  }
}

站点构建时间:2026/8/24 23:43:17