You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter应用使用ListView.builder加载大量图片时崩溃求助

问题描述

使用ListView.builder展示604张单张大小165KB(总96MB)的图片时,应用启动直接崩溃;仅展示200张时,可运行滚动但一段时间后仍崩溃。已尝试ResizeImage、addAutomaticKeepAlives和shrinkWrap选项,均未解决问题。

代码示例:

main() {
  runApp(
    const Test(),
  );
}

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: ListView.builder(
            itemCount: 200,
            itemBuilder: (context, index) {
              String pageNum = "";

              if ((index + 1) < 10) {
                pageNum = "00${index + 1}";
              } else if ((index + 1) < 100 && (index + 1) > 9) {
                pageNum = "0${index + 1}";
              } else {
                pageNum = "${index + 1}";
              }
              return Image(
                image: AssetImage('images/mushaf_photos_2/page$pageNum.png'),
                fit: BoxFit.fill,
              );
            },
          ),
        ),
      ),
    );
  }
}
解决方案

1. 用缓存库管理本地图片加载

借助cached_network_image处理本地Asset图片,它会自动管理图片的缓存与内存释放,避免一次性加载过多资源:

  • 先添加依赖:flutter pub add cached_network_image
  • 修改加载代码:
return CachedNetworkImage(
  imageUrl: 'asset:///images/mushaf_photos_2/page$pageNum.png',
  fit: BoxFit.fill,
);

2. 精准压缩图片解码尺寸

单独使用ResizeImage可能无效,需结合屏幕尺寸明确指定压缩后的宽高,确保只加载适合当前屏幕的图片尺寸:

return Image(
  image: ResizeImage(
    AssetImage('images/mushaf_photos_2/page$pageNum.png'),
    width: MediaQuery.of(context).size.width.toInt(),
    height: MediaQuery.of(context).size.height.toInt(),
  ),
  fit: BoxFit.fill,
);

3. 给ListView指定固定项高度

在ListView.builder中设置itemExtent,帮助Flutter更高效地回收不可见项的内存:

ListView.builder(
  itemExtent: MediaQuery.of(context).size.height, // 与屏幕高度一致
  itemCount: 604,
  // 其余逻辑不变
)

4. 改用PageView(适合翻页场景)

如果图片是按页浏览的场景,PageView默认只保留当前、前、后三页的图片,内存占用远低于ListView:

PageView.builder(
  itemCount: 604,
  itemBuilder: (context, index) {
    // 图片加载逻辑同上
  },
)

5. 限制全局图片缓存大小

在应用启动时设置ImageCache的最大缓存容量,防止内存溢出:

main() {
  PaintingBinding.instance.imageCache.maximumSizeBytes = 50 * 1024 * 1024; // 限制为50MB
  runApp(const Test());
}

内容的提问来源于stack exchange,提问作者Youcef DOUKHI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 10:17:46