5.5 图片与资源管理

张开发
2026/6/1 16:12:38 15 分钟阅读
5.5 图片与资源管理
图片加载和资源管理是 Flutter 应用的基础能力。高效的图片加载策略、缓存机制和 Asset 管理直接影响 App 的性能和用户体验。一、Asset 资源管理1.1 注册与加载# pubspec.yamlflutter:assets:-assets/images/# 整个目录-assets/icons/-assets/animations/-assets/images/logo.png# 单个文件// 加载图片资源Image.asset(assets/images/logo.png)// 加载不同分辨率自动适配// assets/images/logo.png → 1x// assets/images/2.0x/logo.png → 2x// assets/images/3.0x/logo.png → 3xImage.asset(assets/images/logo.png,width:200,height:200,fit:BoxFit.contain,)// 加载 JSON / 文本文件finaljsonStrawaitrootBundle.loadString(assets/config.json);finalconfigjsonDecode(jsonStr);// 加载字节数据finaldataawaitrootBundle.load(assets/data.bin);1.2 动态加载 Asset// 根据条件加载不同图片Image.asset(isDarkMode?assets/images/logo_dark.png:assets/images/logo_light.png,)// 平台特定资源Image.asset(Platform.isIOS?assets/images/icon_ios.png:assets/images/icon_android.png,)二、网络图片加载2.1 Image.networkImage.network(https://example.com/photo.jpg,width:300,height:200,fit:BoxFit.cover,// 加载中占位loadingBuilder:(context,child,progress){if(progressnull)returnchild;returnCenter(child:CircularProgressIndicator(value:progress.expectedTotalBytes!null?progress.cumulativeBytesLoaded/progress.expectedTotalBytes!:null,),);},// 加载失败占位errorBuilder:(context,error,stackTrace){returnContainer(color:Colors.grey[200],child:constIcon(Icons.broken_image,size:48,color:Colors.grey),);},// ⭐ 限制解码尺寸节省内存cacheWidth:600,cacheHeight:400,)2.2 CachedNetworkImage推荐dependencies:cached_network_image:^3.3.1CachedNetworkImage(imageUrl:product.imageUrl,width:200,height:200,fit:BoxFit.cover,// 加载中骨架屏placeholder:(context,url)Shimmer.fromColors(baseColor:Colors.grey[300]!,highlightColor:Colors.grey[100]!,child:Container(color:Colors.white,width:200,height:200),),// 加载失败errorWidget:(context,url,error)Container(color:Colors.grey[200],child:constIcon(Icons.error_outline),),// 控制缓存memCacheWidth:400,// 内存缓存宽度maxWidthDiskCache:800,// 磁盘缓存最大宽度fadeInDuration:constDuration(milliseconds:300),)2.3 FadeInImage淡入过渡FadeInImage.assetNetwork(placeholder:assets/images/placeholder.png,// 本地占位图image:product.imageUrl,// 网络图片fit:BoxFit.cover,fadeInDuration:constDuration(milliseconds:200),imageErrorBuilder:(context,error,stackTrace){returnImage.asset(assets/images/no_image.png);},)三、SVG 与矢量图dependencies:flutter_svg:^2.0.10importpackage:flutter_svg/flutter_svg.dart;// 加载 Asset SVGSvgPicture.asset(assets/icons/cart.svg,width:24,height:24,colorFilter:ColorFilter.mode(Colors.blue,BlendMode.srcIn),// 着色)// 加载网络 SVGSvgPicture.network(https://example.com/icon.svg,width:32,height:32,)// SVG 字符串SvgPicture.string( svg xmlnshttp://www.w3.org/2000/svg viewBox0 0 24 24 circle cx12 cy12 r10 fillcurrentColor/ /svg )四、图片缓存管理4.1 内存缓存配置voidmain(){PaintingBinding.instance.imageCache..maximumSize200// 最多缓存 200 张图片..maximumSizeBytes10020;// 最大 100MBrunApp(constMyApp());}// 获取缓存状态finalcachePaintingBinding.instance.imageCache;debugPrint(缓存数量:${cache.currentSize}/${cache.maximumSize});debugPrint(缓存大小:${cache.currentSizeBytes~/1024~/1024}MB);4.2 清理缓存// 清理所有图片缓存imageCache.clear();imageCache.clearLiveImages();// 清理 CachedNetworkImage 磁盘缓存importpackage:flutter_cache_manager/flutter_cache_manager.dart;awaitDefaultCacheManager().emptyCache();// 只驱逐特定图片imageCache.evict(AssetImage(assets/large_image.png));4.3 预加载图片// 在进入页面前预加载避免闪烁overridevoiddidChangeDependencies(){super.didChangeDependencies();precacheImage(constAssetImage(assets/images/banner.png),context);precacheImage(NetworkImage(product.imageUrl),context);}五、图片选择与裁剪dependencies:image_picker:^1.0.7image_cropper:^5.0.1importpackage:image_picker/image_picker.dart;importpackage:image_cropper/image_cropper.dart;classImagePickerService{staticfinal_pickerImagePicker();// 从相册选择staticFutureFile?pickFromGallery()async{finalxFileawait_picker.pickImage(source:ImageSource.gallery,maxWidth:1080,// 限制最大宽度maxHeight:1080,imageQuality:85,// 压缩质量 0-100);if(xFilenull)returnnull;returnFile(xFile.path);}// 拍照staticFutureFile?takePhoto()async{finalxFileawait_picker.pickImage(source:ImageSource.camera,preferredCameraDevice:CameraDevice.rear,maxWidth:1080,imageQuality:85,);if(xFilenull)returnnull;returnFile(xFile.path);}// 多选staticFutureListFilepickMultiple({int limit9})async{finalxFilesawait_picker.pickMultiImage(maxWidth:1080,imageQuality:85,limit:limit,);returnxFiles.map((f)File(f.path)).toList();}// 裁剪staticFutureFile?cropImage(FileimageFile)async{finalcroppedFileawaitImageCropper().cropImage(sourcePath:imageFile.path,aspectRatio:constCropAspectRatio(ratioX:1,ratioY:1),uiSettings:[AndroidUiSettings(toolbarTitle:裁剪头像,toolbarColor:Colors.blue,toolbarWidgetColor:Colors.white,cropStyle:CropStyle.circle,),IOSUiSettings(title:裁剪头像,cropStyle:CropStyle.circle),],);if(croppedFilenull)returnnull;returnFile(croppedFile.path);}}六、图片压缩dependencies:flutter_image_compress:^2.1.0importpackage:flutter_image_compress/flutter_image_compress.dart;classImageCompressor{// 压缩到指定质量staticFutureFilecompress(Filefile,{int quality80})async{finaltargetPath${file.parent.path}/compressed_${file.uri.pathSegments.last};finalresultawaitFlutterImageCompress.compressAndGetFile(file.absolute.path,targetPath,quality:quality,minWidth:1080,minHeight:1080,);returnFile(result!.path);}// 压缩到指定大小如 200KBstaticFutureFilecompressToSize(Filefile,int maxKB)async{int quality90;Filecompressedfile;while(quality10){compressedawaitcompress(file,quality:quality);finalsizeKBawaitcompressed.length()~/1024;if(sizeKBmaxKB)break;quality-10;}returncompressed;}}小结功能推荐方案Asset 图片Image.asset 多分辨率网络图片CachedNetworkImage带缓存/占位/错误处理SVGflutter_svg图片选择image_picker图片裁剪image_cropper图片压缩flutter_image_compress预加载precacheImage内存管理cacheWidthimageCache配置 下一节继续阅读后续章节

更多文章