XNZImage
English | 中文
A Flutter image loading package with unified rendering and cache management. It supports network, memory, file, and asset image sources, and provides an extensible architecture for extra formats.
Overview
This repository uses a core + extension architecture:
xnz_image: main public API (XNZNetworkImage,XNZMemoryImage,XNZFileImage,XNZAssetImage,XNZCacheManager, etc.)xnz_image_core: internal capabilities (cache, downloader, extension mechanism)xnz_image_svg: SVG support extensionxnz_image_avif: AVIF support extension
Installation
1) Base package
dependencies:
xnz_image: ^0.1.12
2) Optional extensions
dependencies:
xnz_image: ^0.1.12
xnz_image_svg: ^0.1.12
xnz_image_avif: ^0.1.12
For local development in this monorepo, you may use path dependencies.
Register Extensions
import 'package:flutter/widgets.dart';
import 'package:xnz_image/xnz_image.dart';
import 'package:xnz_image_svg/xnz_image_svg.dart';
import 'package:xnz_image_avif/xnz_image_avif.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
XNZImageLogs.showLogs = true;
XNZImageMemoryObserver().init();
XNZImage.support(XNZImageSvg());
XNZImage.support(XNZImageAvif());
runApp(const MyApp());
}
Supported Formats
- Default (
xnz_imageonly): common bitmap formats such aspng,jpg,jpeg,gif,webp,bmp - With
xnz_image_svgregistered:svg,svgz - With
xnz_image_avifregistered:avif,avifs(including animated AVIF duration override)
Basic Widgets
Network
XNZNetworkImage(
imageUrl: 'https://picsum.photos/800/480',
width: 300,
height: 180,
fit: BoxFit.cover,
)
Memory
XNZMemoryImage(
bytes: yourBytes,
width: 300,
height: 180,
fit: BoxFit.cover,
)
File
XNZFileImage(
file: File('/path/to/local/image.avif'),
width: 300,
height: 180,
fit: BoxFit.cover,
)
Asset
XNZAssetImage(
assetName: 'assets/images/banner.avif',
width: 300,
height: 180,
fit: BoxFit.cover,
)
Use With Flutter Image
Image(
image: XNZNetworkImageProvider('https://picsum.photos/800/480'),
width: 300,
height: 180,
fit: BoxFit.cover,
)
Animated Image Playback
XNZAnimatedImage decodes frames and plays on a timeline. It is suitable for GIF / Animated WebP / APNG,
and can also decode animated AVIF when AVIF support is registered.
Highlights
- Timeline sync:
position,progress,frameIndex - Playback control:
play,pause,resume,replay - Callbacks:
onLoaded,onCompleted - Loop control:
loop - Error fallback:
errorBuilder
Example
final controller = XNZAnimatedImageController();
XNZAnimatedImage(
image: XNZNetworkImageProvider('https://example.com/demo.gif'),
controller: controller,
autoPlay: true,
loop: true,
fit: BoxFit.contain,
onLoaded: (duration, fps, frameCount) {
debugPrint('duration=$duration fps=$fps frames=$frameCount');
},
onCompleted: (completedLoops) {
debugPrint('completedLoops=$completedLoops');
},
loadingBuilder: (_) => const Center(child: CircularProgressIndicator()),
errorBuilder: (context, error, stackTrace) {
return const Center(child: Text('Animated image load failed'));
},
)
Unified Render Hook (renderBuilder)
Use renderBuilder to wrap default rendering behavior for bitmap and custom formats:
XNZNetworkImage(
imageUrl: url,
renderBuilder: (context, child) {
return ClipRRect(
borderRadius: BorderRadius.circular(12),
child: child,
);
},
)
If renderBuilder returns null, the widget falls back to default rendering.
Cache Manager
import 'package:xnz_image/xnz_image.dart';
Future<void> printCacheUsage() async {
final cacheManager = XNZCacheManager();
final memoryBytes = cacheManager.getMemoryCacheBytes();
final diskBytes = await cacheManager.getDiskCacheBytes();
print('Memory cache: $memoryBytes B');
print('Disk cache: $diskBytes B');
}
Future<void> clearAllCache() async {
await XNZCacheManager().clearAll();
}
Future<void> clearUnusedDiskCache() async {
// Delete disk cache entries not used for 30 days.
final deleted = await XNZCacheManager().clearUnusedDiskCache(
const Duration(days: 30),
);
print('Deleted disk cache files: $deleted');
}
Platform Notes
- Web is currently not supported.
- Using unsupported paths on Web may throw
UnsupportedError.
Run Example
Minimal pub example:
flutter run -t example/main.dart
More complete demo apps are under:
examples/example_bitmapexamples/example_bitmap_svgexamples/example_bitmap_avifexamples/example_bitmap_svg_avif
概览
xnz_image:对外主 API(XNZNetworkImage、XNZMemoryImage、XNZFileImage、XNZAssetImage、XNZCacheManager等)xnz_image_core:内部基础能力(缓存、下载、扩展机制)xnz_image_svg:SVG 格式支持扩展xnz_image_avif:AVIF 格式支持扩展
安装
1) 基础能力
dependencies:
xnz_image: ^0.1.12
2) 可选扩展(按需)
dependencies:
xnz_image: ^0.1.12
xnz_image_svg: ^0.1.12
xnz_image_avif: ^0.1.12
在本仓库联调时可使用 path 依赖。
扩展注册
import 'package:flutter/widgets.dart';
import 'package:xnz_image/xnz_image.dart';
import 'package:xnz_image_svg/xnz_image_svg.dart';
import 'package:xnz_image_avif/xnz_image_avif.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
XNZImageLogs.showLogs = true;
XNZImageMemoryObserver().init();
XNZImage.support(XNZImageSvg());
XNZImage.support(XNZImageAvif());
runApp(const MyApp());
}
支持格式
- 默认(只引入
xnz_image):png、jpg、jpeg、gif、webp、bmp - 引入并注册
xnz_image_svg后:svg、svgz - 引入并注册
xnz_image_avif后:avif、avifs(支持 AVIF 动图时长覆盖参数)
基础组件示例
网络图片
XNZNetworkImage(
imageUrl: 'https://picsum.photos/800/480',
width: 300,
height: 180,
fit: BoxFit.cover,
)
内存图片
XNZMemoryImage(
bytes: yourBytes,
width: 300,
height: 180,
fit: BoxFit.cover,
)
文件图片
XNZFileImage(
file: File('/path/to/local/image.avif'),
width: 300,
height: 180,
fit: BoxFit.cover,
)
Asset 图片
XNZAssetImage(
assetName: 'assets/images/banner.avif',
width: 300,
height: 180,
fit: BoxFit.cover,
)
与 Flutter Image 组合
Image(
image: XNZNetworkImageProvider('https://picsum.photos/800/480'),
width: 300,
height: 180,
fit: BoxFit.cover,
)
动画播放组件
XNZAnimatedImage 支持帧解码播放,适用于 GIF / Animated WebP / APNG。
注册 AVIF 扩展后,也可自动处理 AVIF 动图。
能力概览
- 精准 UI 同步:
position、progress、frameIndex - 播放控制:
play、pause、resume、replay - 回调:
onLoaded、onCompleted - 循环开关:
loop - 异常兜底:
errorBuilder
用法示例
final controller = XNZAnimatedImageController();
XNZAnimatedImage(
image: XNZNetworkImageProvider('https://example.com/demo.gif'),
controller: controller,
autoPlay: true,
loop: true,
fit: BoxFit.contain,
onLoaded: (duration, fps, frameCount) {
debugPrint('duration=$duration fps=$fps frames=$frameCount');
},
onCompleted: (completedLoops) {
debugPrint('completedLoops=$completedLoops');
},
loadingBuilder: (_) => const Center(child: CircularProgressIndicator()),
errorBuilder: (context, error, stackTrace) {
return const Center(child: Text('Animated image load failed'));
},
)
统一渲染回调(renderBuilder)
使用 renderBuilder 可以统一包装默认渲染结果:
XNZNetworkImage(
imageUrl: url,
renderBuilder: (context, child) {
return ClipRRect(
borderRadius: BorderRadius.circular(12),
child: child,
);
},
)
当 renderBuilder 返回 null 时,会回退到默认渲染。
缓存管理
import 'package:xnz_image/xnz_image.dart';
Future<void> printCacheUsage() async {
final cacheManager = XNZCacheManager();
final memoryBytes = cacheManager.getMemoryCacheBytes();
final diskBytes = await cacheManager.getDiskCacheBytes();
print('Memory cache: $memoryBytes B');
print('Disk cache: $diskBytes B');
}
Future<void> clearAllCache() async {
await XNZCacheManager().clearAll();
}
Future<void> clearUnusedDiskCache() async {
// 删除 30 天未命中的磁盘缓存。
final deleted = await XNZCacheManager().clearUnusedDiskCache(
const Duration(days: 30),
);
print('Deleted disk cache files: $deleted');
}
平台说明
- 当前暂不支持 Web。
- 在 Web 端使用相关能力可能抛出
UnsupportedError。
运行示例
最小示例:
flutter run -t example/main.dart
完整演示项目在:
examples/example_bitmapexamples/example_bitmap_svgexamples/example_bitmap_avifexamples/example_bitmap_svg_avif
Libraries
- xnz_image
- Public entrypoint for the
xnz_imagepackage.