


作者 :孟少康(世人万千)
仓库地址 :https://gitcode.com/feng8403000/FlutterfromBeginnertoAdvancedForHarmonyOS.git
联系邮箱:372699828@qq.com
概述
Image组件是Flutter中用于显示图片的核心组件,它支持从多种来源加载图片,包括网络、本地资源、文件等。掌握Image组件的用法对于创建视觉丰富的用户界面至关重要。
基础用法
从网络加载图片
dart
Image.network("https://example.com/image.jpg");
从本地资源加载图片
dart
Image.asset("assets/images/logo.png");
从文件加载图片
dart
Image.file(File("/path/to/image.png"));
从内存加载图片
dart
Image.memory(imageBytes);
构造函数详解
Image.network
dart
Image.network(
String url, {
Key? key,
double? scale,
this.width,
this.height,
Color? color,
BlendMode? colorBlendMode,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect? centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = false,
String? semanticLabel,
bool excludeFromSemantics = false,
double? width,
double? height,
...
});
Image.asset
dart
Image.asset(
String name, {
Key? key,
AssetBundle? bundle,
double? scale,
this.width,
this.height,
Color? color,
BlendMode? colorBlendMode,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect? centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = false,
String? semanticLabel,
bool excludeFromSemantics = false,
String? package,
});
核心属性详解
width和height属性
width和height属性定义图片的显示尺寸。
dart
Image.network(
"https://example.com/image.jpg",
width: 200,
height: 200,
);
fit属性
fit属性定义图片如何适应容器的尺寸。
dart
Image.network(
"https://example.com/image.jpg",
width: 200,
height: 200,
fit: BoxFit.cover,
);
支持的fit模式:
| fit模式 | 说明 |
|---|---|
| BoxFit.fill | 拉伸填充整个容器,可能会变形 |
| BoxFit.contain | 保持宽高比,完整显示图片,可能留有空白 |
| BoxFit.cover | 保持宽高比,覆盖整个容器,可能裁剪部分内容 |
| BoxFit.fitWidth | 保持宽高比,宽度填满容器 |
| BoxFit.fitHeight | 保持宽高比,高度填满容器 |
| BoxFit.none | 不缩放,居中显示 |
| BoxFit.scaleDown | 缩小到合适大小,不放大 |
alignment属性
alignment属性定义图片在容器中的对齐方式。
dart
Image.network(
"https://example.com/image.jpg",
width: 200,
height: 200,
alignment: Alignment.topLeft,
);
支持的对齐方式:
Alignment.topLeftAlignment.topCenterAlignment.topRightAlignment.centerLeftAlignment.centerAlignment.centerRightAlignment.bottomLeftAlignment.bottomCenterAlignment.bottomRight
repeat属性
repeat属性定义图片如何重复填充容器。
dart
Image.network(
"https://example.com/pattern.png",
width: 300,
height: 300,
repeat: ImageRepeat.repeat,
);
支持的重复模式:
ImageRepeat.noRepeat:不重复ImageRepeat.repeat:水平和垂直重复ImageRepeat.repeatX:仅水平重复ImageRepeat.repeatY:仅垂直重复
color和colorBlendMode属性
color和colorBlendMode属性用于给图片着色。
dart
Image.network(
"https://example.com/image.jpg",
color: Colors.blue,
colorBlendMode: BlendMode.color,
);
centerSlice属性
centerSlice属性用于九片拉伸(9-patch)技术。
dart
Image.asset(
"assets/images/frame.png",
width: 300,
height: 200,
centerSlice: const Rect.fromLTRB(10, 10, 10, 10),
);
matchTextDirection属性
matchTextDirection属性用于根据文本方向翻转图片。
dart
Image.network(
"https://example.com/image.jpg",
matchTextDirection: true,
);
图片加载与缓存
设置缓存宽度和高度
dart
Image.network(
"https://example.com/image.jpg",
cacheWidth: 300,
cacheHeight: 300,
);
禁用缓存
dart
Image.network(
"https://example.com/image.jpg",
cacheWidth: 0,
cacheHeight: 0,
);
设置加载超时
dart
Image.network(
"https://example.com/image.jpg",
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
}
return const CircularProgressIndicator();
},
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.error);
},
);
实际应用示例
圆角图片
dart
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
"https://example.com/image.jpg",
width: 100,
height: 100,
fit: BoxFit.cover,
),
);
圆形头像
dart
ClipOval(
child: Image.network(
"https://example.com/avatar.jpg",
width: 80,
height: 80,
fit: BoxFit.cover,
),
);
带边框的图片
dart
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blue, width: 2),
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.all(2),
child: ClipRRect(
borderRadius: BorderRadius.circular(6),
child: Image.network(
"https://example.com/image.jpg",
width: 150,
height: 150,
fit: BoxFit.cover,
),
),
);
渐变色叠加
dart
Stack(
children: [
Image.network(
"https://example.com/image.jpg",
width: 300,
height: 200,
fit: BoxFit.cover,
),
Container(
width: 300,
height: 200,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.transparent,
Colors.black.withOpacity(0.5),
],
),
),
),
const Positioned(
bottom: 10,
left: 10,
child: Text(
"图片标题",
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
],
);
图片列表
dart
GridView.count(
crossAxisCount: 3,
padding: const EdgeInsets.all(8),
crossAxisSpacing: 8,
mainAxisSpacing: 8,
children: [
Image.network("https://example.com/img1.jpg", fit: BoxFit.cover),
Image.network("https://example.com/img2.jpg", fit: BoxFit.cover),
Image.network("https://example.com/img3.jpg", fit: BoxFit.cover),
Image.network("https://example.com/img4.jpg", fit: BoxFit.cover),
Image.network("https://example.com/img5.jpg", fit: BoxFit.cover),
Image.network("https://example.com/img6.jpg", fit: BoxFit.cover),
],
);
图片懒加载
dart
class LazyImage extends StatelessWidget {
final String url;
const LazyImage({super.key, required this.url});
@override
Widget build(BuildContext context) {
return Image.network(
url,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
}
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: null,
),
);
},
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.broken_image);
},
);
}
}
图片预览
dart
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(backgroundColor: Colors.black),
body: Center(
child: Image.network(
"https://example.com/image.jpg",
fit: BoxFit.contain,
),
),
),
),
);
},
child: Image.network(
"https://example.com/image.jpg",
width: 150,
height: 100,
fit: BoxFit.cover,
),
);
占位图和错误处理
dart
Image.network(
"https://example.com/image.jpg",
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
}
return Container(
color: Colors.grey[200],
child: const Center(
child: CircularProgressIndicator(),
),
);
},
errorBuilder: (context, error, stackTrace) {
return Container(
color: Colors.grey[100],
child: const Center(
child: Icon(Icons.error, color: Colors.red),
),
);
},
);
性能优化建议
设置合适的缓存尺寸
dart
Image.network(
"https://example.com/image.jpg",
cacheWidth: 300,
cacheHeight: 300,
);
避免不必要的图片加载
dart
// 不好的做法:每次build都重新加载
Widget build(BuildContext context) {
return Image.network("https://example.com/image.jpg");
}
// 好的做法:使用CachedNetworkImage或类似缓存方案
CachedNetworkImage(
imageUrl: "https://example.com/image.jpg",
);
使用占位图
dart
Image.network(
"https://example.com/image.jpg",
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const CircularProgressIndicator();
},
);
释放图片资源
dart
@override
void dispose() {
// 如果使用了自定义ImageProvider,需要手动释放资源
super.dispose();
}
常见问题
图片不显示怎么办?
检查以下几点:
- URL是否正确
- 网络是否可用
- 是否添加了网络权限
- 是否配置了assets资源
如何设置图片圆角?
使用ClipRRect组件。
dart
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network("https://example.com/image.jpg"),
);
如何实现圆形图片?
使用ClipOval组件。
dart
ClipOval(
child: Image.network("https://example.com/image.jpg"),
);
图片拉伸变形怎么办?
使用fit属性控制缩放方式。
dart
Image.network(
"https://example.com/image.jpg",
fit: BoxFit.cover, // 保持宽高比
);
如何加载本地图片?
首先在pubspec.yaml中配置:
yaml
flutter:
assets:
- assets/images/
然后使用Image.asset:
dart
Image.asset("assets/images/logo.png");
总结
Image组件是Flutter中显示图片的核心组件,支持多种图片来源和丰富的配置选项。以下是一些关键点:
- 图片来源:网络、本地资源、文件、内存
- 尺寸控制:width、height、fit属性
- 样式设置:圆角、边框、渐变叠加
- 加载状态:loadingBuilder、errorBuilder
- 性能优化:缓存尺寸、占位图、资源释放
掌握Image组件的用法对于创建视觉丰富的用户界面至关重要。
参考资料: