Flutter图像与媒体控件小结
在Flutter中,处理图像和媒体控件(例如视频和音频)变得非常简单和高效。
图像控件
本地图片Image.asset
要显示应用程序中的本地图片,可以使用Image.asset:
属性解析
Image.asset(
String name, {
super.key,
AssetBundle? bundle,
this.frameBuilder,
this.errorBuilder,
this.semanticLabel,
this.excludeFromSemantics = false,
double? scale,
this.width,
this.height,
this.color,
this.opacity,
this.colorBlendMode,
this.fit,
this.alignment = Alignment.center,
this.repeat = ImageRepeat.noRepeat,
this.centerSlice,
this.matchTextDirection = false,
this.gaplessPlayback = false,
this.isAntiAlias = false,
String? package,
this.filterQuality = FilterQuality.low,
int? cacheWidth,
int? cacheHeight,
})
- name: 图片资源的名称或 URL。
- key: 唯一标识这个组件的键值。
- bundle: 用于加载图片的资源包。
- frameBuilder: 自定义图片构建方式的构建器函数。
- errorBuilder: 处理加载图片时错误的构建器函数。
- semanticLabel: 用于无障碍访问的标签。
- excludeFromSemantics: 是否将图片排除在语义树之外。
- scale: 图片的缩放因子。
- width: 图片的宽度。
- height: 图片的高度。
- color: 用于给图片着色的颜色。
- opacity: 图片的不透明度。
- colorBlendMode: 应用颜色滤镜时使用的混合模式。
- fit: 图片如何适配其外框。
- alignment: 图片在其边界内如何对齐。
- repeat: 如果图片没有填满其框,如何重复图片。
- centerSlice: 描述九切片图像中心部分的矩形。
- matchTextDirection: 当文本方向为 RTL(从右到左)时是否水平翻转图片。
- gaplessPlayback: 当图像提供者改变时,是否继续显示旧图片。
- isAntiAlias: 是否对图片应用抗锯齿处理。
- package: 从哪个包加载图片的包名。
- filterQuality: 图片过滤的质量。
- cacheWidth: 缓存图片的宽度。
- cacheHeight: 缓存图片的高度。
示例
class ImageWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Image.asset 示例')),
body: Center(
child: Image.asset(
'assets/1.jpeg',
key: Key('image_key'),
scale: 2.0,
width: 200,
height: 200,
// color: Colors.red,
colorBlendMode: BlendMode.colorBurn,
fit: BoxFit.cover,
alignment: Alignment.topLeft,
repeat: ImageRepeat.noRepeat,
matchTextDirection: false,
gaplessPlayback: true,
isAntiAlias: true,
filterQuality: FilterQuality.high,
cacheWidth: 100,
cacheHeight: 100,
),
),
),
);
}
}
![](https://img-blog.csdnimg.cn/direct/c380778059904582ae61a9809a279049.png)
![](https://img-blog.csdnimg.cn/direct/9e25ae9fa6e44d85918a13ba86e320e2.png)
备注:
如图:
网络图片Image.network
要显示来自网络的图片,可以使用Image.network:
属性解析
Image.network(
String src, {
super.key,
double scale = 1.0,
this.frameBuilder,
this.loadingBuilder,
this.errorBuilder,
this.semanticLabel,
this.excludeFromSemantics = false,
this.width,
this.height,
this.color,
this.opacity,
this.colorBlendMode,
this.fit,
this.alignment = Alignment.center,
this.repeat = ImageRepeat.noRepeat,
this.centerSlice,
this.matchTextDirection = false,
this.gaplessPlayback = false,
this.filterQuality = FilterQuality.low,
this.isAntiAlias = false,
Map<String, String>? headers,
int? cacheWidth,
int? cacheHeight,
})
- src (String): 图像的 URL,是必填项。
- key (Key): 控件的唯一标识符,用于树形结构和状态管理。
- scale (double): 图像的缩放比例,默认值为 1.0。
- frameBuilder (ImageFrameBuilder?): 绘制每一帧时的回调函数。
- loadingBuilder (ImageLoadingBuilder?): 图像正在加载时的回调函数。
- errorBuilder (ImageErrorWidgetBuilder?): 当图像加载失败时构建错误组件的回调函数。
- semanticLabel (String?): 语义标签,用于无障碍支持。
- excludeFromSemantics (bool): 是否将该图像从语义树中排除,默认值为 false。
- width (double?): 图像的宽度。
- height (double?): 图像的高度。
- color (Color?): 图像的颜色,会与 colorBlendMode 一起使用。
- opacity (Animation?): 图像的不透明度,可以使用动画。
- colorBlendMode (BlendMode?): 图像颜色的混合模式。
- fit (BoxFit?): 图像的适应方式,例如填充、包含等。
- alignment (Alignment): 图像的对齐方式,默认值为 Alignment.center。
- repeat (ImageRepeat): 图像的重复方式,默认值为 ImageRepeat.noRepeat。
- centerSlice (Rect?): 中心切片矩形,用于图像拉伸。
- matchTextDirection (bool): 是否根据文本方向来镜像翻转图像,默认值为 false。
- gaplessPlayback (bool): 是否在更改图像时持续显示上一张图像,直到新图像可用,默认值为 false。
- filterQuality (FilterQuality): 图像的过滤质量,默认值为 FilterQuality.low。
- isAntiAlias (bool): 是否对图像进行抗锯齿处理,默认值为 false。
- headers (Map<String, String>?): 用于请求图像的 HTTP 头信息。
- cacheWidth (int?): 缓存图像的宽度。
- cacheHeight (int?): 缓存图像的高度。
示例
class ImageWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Image.network 示例')),
body: Center(
child: Image.network(
'https://img1.baidu.com/it/u=4122344780,2704161739&fm=253&fmt=auto&app=138&f=JPEG?w=650&h=488',
scale: 2.0,
width: 200,
height: 200,
color: Colors.blue,
colorBlendMode: BlendMode.colorBurn,
fit: BoxFit.cover,
alignment: Alignment.topLeft,
repeat: ImageRepeat.noRepeat,
matchTextDirection: false,
gaplessPlayback: true,
isAntiAlias: true,
filterQuality: FilterQuality.high,
headers: {'Authorization': 'Bearer token'},
cacheWidth: 100,
cacheHeight: 100,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
(loadingProgress.expectedTotalBytes ?? 1)
: null,
),
);
}
},
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
return Icon(Icons.error);
},
),
),
),
);
}
}
ImageProvider
ImageProvider 是 Flutter 中一个抽象类,用于描述如何获取图像数据。常见的 ImageProvider 子类包括 AssetImage、NetworkImage 和 FileImage,分别用于加载本地资源图片、网络图片和文件系统中的图片。
AssetImage
AssetImage 是 Flutter 框架中用于从应用程序的资产目录中加载图像的类。它提供了一种便捷的方法来管理和使用本地图像资源
属性解析
const AssetImage(
this.assetName, {
this.bundle,
this.package,
})
- assetName (String): 资产图像文件的路径,是必填项。例如,assets/images/my_image.png。
- bundle (AssetBundle?): 用于从指定资源包中加载图像,默认为 rootBundle。
- package (String?): 指定图像所属的包名,用于加载包内资源。
扩展
如果你正在开发一个 Flutter 包,你可能会想要加载包自身的资源。在这种情况下,你需要指定 package 参数,如下所示:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('AssetImage 示例')),
body: Center(
child: Image(
image: AssetImage(
'assets/images/my_image.png',
package: 'my_package_name',
),
width: 200,
height: 200,
fit: BoxFit.cover,
),
),
),
);
}
}
NetworkImage
NetworkImage 是 Flutter 框架中用于从网络加载图像的类。它提供了一种便捷的方法来管理和使用网络图像资源
属性解析
const factory NetworkImage(String url, { double scale, Map<String, String>? headers })
- url (String): 图像的 URL,是必填项。例如,https://example.com/my_image.png。
- scale (double): 图像的缩放比例,默认值为 1.0。
- headers (Map<String, String>?): 用于请求图像的 HTTP 头信息。
FileImage
FileImage 是 Flutter 框架中用于从本地文件系统加载图像的类。它提供了一种便捷的方法来管理和使用存储在设备上的图像资源。
属性解析
const FileImage(this.file, { this.scale = 1.0 });
- file (File): 本地文件对象,是必填项。需要引入 dart:io 包中的 File 类。
- scale (double): 图像的缩放比例,默认值为 1.0。
示例
class ImageWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('FileImage 示例')),
body: Center(
child: FutureBuilder<File>(
future: _getLocalFile(), // 获取本地文件的路径
builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return Image(
image: FileImage(snapshot.data!),
width: 200,
height: 200,
fit: BoxFit.cover,
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator(); // 显示进度条
} else {
return Icon(Icons.error); // 显示错误图标
}
},
),
),
),
);
}
Future<File> _getLocalFile() async {
// 获取应用程序文档目录
final directory = await getApplicationDocumentsDirectory();
// 替换为你本地图像的实际路径
String filePath = '${directory.path}/your_local_image.png';
return File(filePath);
}
}
在这个示例中,我们首先创建了一个 FutureBuilder,用于异步加载本地文件。_getLocalFile 函数返回一个 File 对象,该对象指向本地文件系统中的图像文件。
一旦文件加载完成,我们使用 FileImage 从本地文件系统中加载图像,并通过 Image 小部件将其展示出来。此外,还设置了图像的宽度、高度和适应方式(BoxFit.cover)。
请注意,在实际应用中,你需要根据具体需求替换 _getLocalFile 函数中的文件路径。
使用示例中的本地文件访问权限
请确保您的应用具有访问本地存储的权限。对于 Android,你需要在 AndroidManifest.xml 中添加相应的权限声明,例如:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
对于 iOS,你需要在 Info.plist 文件中添加相应的键值对,例如:
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问您的相册</string>
<key>NSCameraUsageDescription</key>
<string>需要使用您的相机拍照</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要使用您的麦克风录音</string>
通过这些配置,您可以确保应用程序有适当的权限来访问本地文件系统,从而正确加载和显示本地图像。
Image
显示图片,包括网络图片和本地图片。
属性解析
const Image({
super.key,
required this.image,
this.frameBuilder,
this.loadingBuilder,
this.errorBuilder,
this.semanticLabel,
this.excludeFromSemantics = false,
this.width,
this.height,
this.color,
this.opacity,
this.colorBlendMode,
this.fit,
this.alignment = Alignment.center,
this.repeat = ImageRepeat.noRepeat,
this.centerSlice,
this.matchTextDirection = false,
this.gaplessPlayback = false,
this.isAntiAlias = false,
this.filterQuality = FilterQuality.low,
})
- image (ImageProvider): 提供图像数据的对象,例如 AssetImage 或 NetworkImage,是必填项。
- key (Key): 控件的唯一标识符,用于树形结构和状态管理。
- frameBuilder (ImageFrameBuilder?): 绘制每一帧时的回调函数。
- loadingBuilder (ImageLoadingBuilder?): 图像正在加载时的回调函数。
- errorBuilder (ImageErrorWidgetBuilder?): 当图像加载失败时构建错误组件的回调函数。
- semanticLabel (String?): 语义标签,用于无障碍支持。
- excludeFromSemantics (bool): 是否将该图像从语义树中排除,默认值为 false。
- width (double?): 图像的宽度。
- height (double?): 图像的高度。
- color (Color?): 图像的颜色,会与 colorBlendMode 一起使用。
- opacity (Animation?): 图像的不透明度,可以使用动画。
- colorBlendMode (BlendMode?): 图像颜色的混合模式。
- fit (BoxFit?): 图像的适应方式,例如填充、包含等。
- alignment (Alignment): 图像的对齐方式,默认值为 Alignment.center。
- repeat (ImageRepeat): 图像的重复方式,默认值为 ImageRepeat.noRepeat。
- centerSlice (Rect?): 中心切片矩形,用于图像拉伸。
- matchTextDirection (bool): 是否根据文本方向来镜像翻转图像,默认值为 false。
- gaplessPlayback (bool): 是否在更改图像时持续显示上一张图像,直到新图像可用,默认值为 false。
- isAntiAlias (bool): 是否对图像进行抗锯齿处理,默认值为 false。
- filterQuality (FilterQuality): 图像的过滤质量,默认值为 FilterQuality.low。
示例
class ImageWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Image 示例')),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// 本地图像
Image(
image: AssetImage('assets/1.jpeg'),
width: 200,
height: 200,
fit: BoxFit.cover,
alignment: Alignment.topLeft,
color: Colors.red.withOpacity(0.5),
colorBlendMode: BlendMode.colorBurn,
isAntiAlias: true,
filterQuality: FilterQuality.high,
),
SizedBox(height: 20),
// 网络图像
Image(
image: NetworkImage(
'https://img1.baidu.com/it/u=4122344780,2704161739&fm=253&fmt=auto&app=138&f=JPEG?w=650&h=488'),
width: 200,
height: 200,
fit: BoxFit.cover,
alignment: Alignment.topLeft,
color: Colors.blue.withOpacity(0.5),
colorBlendMode: BlendMode.colorBurn,
isAntiAlias: true,
filterQuality: FilterQuality.high,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
(loadingProgress.expectedTotalBytes ?? 1)
: null,
),
);
}
},
errorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
return Icon(Icons.error);
},
),
],
),
),
);
}
}
分别展示了如何使用 AssetImage 和 NetworkImage 加载本地和网络图像,并设置了多种属性以展示其灵活性。例如,我们调整了图像的宽高、颜色、混合模式以及其他布局属性。此外,还实现了 loadingBuilder 和 errorBuilder 来处理图像加载过程中的状态和错误。
FadeInImage
FadeInImage 是 Flutter 框架中一个非常有用的小部件,用于在加载网络图像或资源图像时显示占位符,并带有淡入淡出的动画效果。它是常见的用于提升用户体验的方式。
属性解析
const FadeInImage({
super.key,
required this.placeholder,
this.placeholderErrorBuilder,
required this.image,
this.imageErrorBuilder,
this.excludeFromSemantics = false,
this.imageSemanticLabel,
this.fadeOutDuration = const Duration(milliseconds: 300),
this.fadeOutCurve = Curves.easeOut,
this.fadeInDuration = const Duration(milliseconds: 700),
this.fadeInCurve = Curves.easeIn,
this.color,
this.colorBlendMode,
this.placeholderColor,
this.placeholderColorBlendMode,
this.width,
this.height,
this.fit,
this.placeholderFit,
this.filterQuality = FilterQuality.low,
this.placeholderFilterQuality,
this.alignment = Alignment.center,
this.repeat = ImageRepeat.noRepeat,
this.matchTextDirection = false,
})
- placeholder (ImageProvider): 占位符图像,当实际图像正在加载时显示。
- placeholderErrorBuilder (ImageErrorWidgetBuilder?): 当占位符加载失败时构建错误组件的回调函数。
- image (ImageProvider): 实际要显示的图像。
- imageErrorBuilder (ImageErrorWidgetBuilder?): 当实际图像加载失败时构建错误组件的回调函数。
- excludeFromSemantics (bool): 是否将该图像从语义树中排除,默认值为 false。
- imageSemanticLabel (String?): 实际图像的语义标签,用于无障碍支持。
- fadeOutDuration (Duration): 占位符淡出动画的持续时间,默认值为 Duration(milliseconds: 300)。
- fadeOutCurve (Curve): 占位符淡出动画的曲线,默认值为 Curves.easeOut。
- fadeInDuration (Duration): 实际图像淡入动画的持续时间,默认值为 Duration(milliseconds: 700)。
- fadeInCurve (Curve): 实际图像淡入动画的曲线,默认值为 Curves.easeIn。
- color (Color?): 实际图像的颜色,会与 colorBlendMode 一起使用。
- colorBlendMode (BlendMode?): 实际图像颜色的混合模式。
- placeholderColor (Color?): 占位符图像的颜色,会与 placeholderColorBlendMode 一起使用。
- placeholderColorBlendMode (BlendMode?): 占位符图像颜色的混合模式。
- width (double?): 图像的宽度。
- height (double?): 图像的高度。
- fit (BoxFit?): 实际图像的适应方式。
- placeholderFit (BoxFit?): 占位符图像的适应方式。
- filterQuality (FilterQuality): 实际图像的过滤质量,默认值为 FilterQuality.low。
- placeholderFilterQuality (FilterQuality?): 占位符图像的过滤质量。
- alignment (Alignment): 图像的对齐方式,默认值为 Alignment.center。
- repeat (ImageRepeat): 图像的重复方式,默认值为 ImageRepeat.noRepeat。
- matchTextDirection (bool): 是否根据文本方向来镜像翻转图像,默认值为 false。
示例
class ImageWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('FadeInImage 示例')),
body: Center(
child: FadeInImage(
placeholder: AssetImage('assets/1.jpeg'),
image: NetworkImage(
'https://img1.baidu.com/it/u=4122344780,2704161739&fm=253&fmt=auto&app=138&f=JPEG?w=650&h=488'),
placeholderErrorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
return Icon(Icons.error); // 显示占位符加载失败的图标
},
imageErrorBuilder:
(BuildContext context, Object error, StackTrace? stackTrace) {
return Icon(Icons.error); // 显示实际图像加载失败的图标
},
fadeInDuration: Duration(milliseconds: 500), // 实际图像淡入动画的持续时间
fadeOutDuration: Duration(milliseconds: 200), // 占位符淡出动画的持续时间
fit: BoxFit.cover,
width: 300,
height: 300,
),
),
),
);
}
}
MemoryImage
MemoryImage 是 Flutter 框架中用于从内存中的字节数组加载图像的类。它提供了一种便捷的方法来管理和使用以字节数组形式存在的图像数据
属性解析
const MemoryImage(this.bytes, { this.scale = 1.0 });
- bytes (Uint8List): 图像数据的字节数组,是必填项。
- scale (double): 图像的缩放比例,默认值为 1.0。
示例
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('MemoryImage 示例')),
body: Center(
child: FutureBuilder<Uint8List>(
future: _loadImageBytes(), // 模拟加载图像字节数据
builder: (BuildContext context, AsyncSnapshot<Uint8List> snapshot) {
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return Image(
image: MemoryImage(snapshot.data!),
width: 200,
height: 200,
fit: BoxFit.cover,
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator(); // 显示进度条
} else {
return Icon(Icons.error); // 显示错误图标
}
},
),
),
),
);
}
Future<Uint8List> _loadImageBytes() async {
// 模拟从网络或本地资源加载图像字节数据
// 此处应替换为实际的图像加载逻辑,例如通过 HTTP 请求获取图像字节数据
await Future.delayed(Duration(seconds: 2)); // 模拟网络延迟
String base64Image = "iVBORw0KGgoAAAANSUhEUgAAAAUA" // 这是一个简单的 base64 编码图像
"AAAAFQMAAABldHUmAAAAAXNSR0IArs4c6QAAABxp"
"RE9UAAAAAgAAAAAAAAABAAAAKAAAAAEAAAAA";
return Uint8List.fromList(base64Decode(base64Image));
}
}
在这个示例中,我们首先定义了一个 FutureBuilder,用于异步加载图像的字节数据。_loadImageBytes 函数模拟了一个异步操作,从而返回一个 Uint8List 类型的图像数据。在实际应用中,这可能包括从网络请求获取图像数据,或者从本地文件读取图像数据。
一旦图像字节数据加载完成,我们使用 MemoryImage 从字节数组中加载图像,并通过 Image 小部件将其展示出来。此外,还设置了图像的宽度、高度和适应方式(BoxFit.cover)。
请注意,在 _loadImageBytes 函数中,我们使用了示例性的数据加载逻辑,实际应用中应替换为真实的图像加载逻辑,例如通过 HTTP 请求获取图像字节数据。
视频与音频
VideoPlayer:
播放视频,需要引入 video_player 包
地址 video_player
AudioPlayer:
播放音频,通常需要第三方包如 audioplayers
地址audioplayers