
一、ImageProvider概述
ImageProvider是Flutter中加载图片数据的抽象接口,支持多种图片来源。
ImageProvider类型
ImageProvider
NetworkImage
AssetImage
FileImage
MemoryImage
网络URL
项目资源
本地文件
内存数据
| ImageProvider | 说明 | 缓存 | 性能 |
|---|---|---|---|
| NetworkImage | 从网络加载 | 自动缓存 | 中等 |
| AssetImage | 从资源加载 | 打包在应用中 | 快 |
| FileImage | 从文件加载 | 无缓存 | 中等 |
| MemoryImage | 从内存加载 | 无需缓存 | 最快 |
二、NetworkImage
基础用法
dart
Image.network(
'https://example.com/image.jpg',
)
带参数的网络图片
dart
Image.network(
'https://example.com/image.jpg',
width: 200,
height: 200,
fit: BoxFit.cover,
)
带缓存的网络图片
dart
Image.network(
'https://example.com/image.jpg',
cacheWidth: 400, // 缓存时缩放到400宽
cacheHeight: 400,
width: 200,
height: 200,
)
三、AssetImage
1. 添加资源到pubspec.yaml
yaml
flutter:
assets:
- assets/images/
- assets/icons/
2. 使用资源图片
dart
Image.asset(
'assets/images/logo.png',
)
带样式的资源图片
dart
Image.asset(
'assets/images/background.jpg',
fit: BoxFit.cover,
width: double.infinity,
height: 200,
)
四、FileImage
加载本地文件
dart
Image.file(
File('/path/to/image.jpg'),
)
加载用户选择的图片
dart
class FileImageExample extends StatefulWidget {
@override
State<FileImageExample> createState() => _FileImageExampleState();
}
class _FileImageExampleState extends State<FileImageExample> {
File? _image;
Future<void> _pickImage() async {
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
setState(() {
_image = File(pickedFile.path);
});
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
if (_image != null)
Image.file(
_image!,
width: 200,
height: 200,
fit: BoxFit.cover,
)
else
Container(
width: 200,
height: 200,
color: Colors.grey.shade300,
child: Icon(Icons.image),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: _pickImage,
child: Text('选择图片'),
),
],
);
}
}
五、MemoryImage
加载内存中的图片
dart
Image.memory(
base64Decode(imageBytes),
)
实际应用示例
dart
class MemoryImageExample extends StatelessWidget {
final Uint8List imageBytes;
const MemoryImageExample({
super.key,
required this.imageBytes,
});
@override
Widget build(BuildContext context) {
return Image.memory(
imageBytes,
width: 200,
height: 200,
fit: BoxFit.cover,
);
}
}
六、Provider选择建议
网络
应用资源
用户文件
内存数据
选择ImageProvider
图片来源
NetworkImage
AssetImage
FileImage
MemoryImage
自动缓存
需要网络
打包速度快
体积固定
动态加载
需要权限
显示最快
占用内存
七、完整示例
dart
class ImageProvidersExample extends StatelessWidget {
const ImageProvidersExample({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Image Providers')),
body: ListView(
padding: EdgeInsets.all(16),
children: [
_buildSection('NetworkImage'),
_buildNetworkImageCard(),
SizedBox(height: 24),
_buildSection('AssetImage'),
_buildAssetImageCard(),
SizedBox(height: 24),
_buildSection('FileImage'),
_buildFileImageCard(),
SizedBox(height: 24),
_buildSection('MemoryImage'),
_buildMemoryImageCard(),
],
),
);
}
Widget _buildSection(String title) {
return Text(
title,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
);
}
Widget _buildNetworkImageCard() {
return Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'网络图片',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 12),
Image.network(
'https://via.placeholder.com/400x200',
width: double.infinity,
height: 150,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Container(
height: 150,
color: Colors.grey.shade300,
child: Center(
child: Text('加载失败'),
),
);
},
),
],
),
),
);
}
Widget _buildAssetImageCard() {
return Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'资源图片',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 12),
Container(
height: 150,
decoration: BoxDecoration(
color: Colors.blue.shade100,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Icon(Icons.image, size: 64, color: Colors.blue),
),
),
],
),
),
);
}
Widget _buildFileImageCard() {
return Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'文件图片',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 12),
Container(
height: 150,
decoration: BoxDecoration(
color: Colors.green.shade100,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.folder, size: 64, color: Colors.green),
SizedBox(height: 8),
Text('从文件加载'),
],
),
),
),
],
),
),
);
}
Widget _buildMemoryImageCard() {
return Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'内存图片',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 12),
Container(
height: 150,
decoration: BoxDecoration(
color: Colors.orange.shade100,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.memory, size: 64, color: Colors.orange),
SizedBox(height: 8),
Text('从内存加载'),
],
),
),
),
],
),
),
);
}
}
八、最佳实践
| 实践 | 说明 | 效果 |
|---|---|---|
| 网络图片加缓存 | 使用cache参数 | 提升性能 |
| 资源图片打包 | 预加载到应用 | 加载快速 |
| 错误处理 | 添加errorBuilder | 体验友好 |
| 加载状态 | 添加loadingBuilder | 用户明确 |
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net