作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :[email protected]
本文地址:https://blog.csdn.net/qq_28550263/article/details/134344516
本文介绍了Flutter框架中 BoxFit 枚举不同枚举值的含义,以及归纳了开发中常见的以 BoxFit 为值的组件,如FittedBox组件Image、FadeInImage等等;以及非组件的工具,如DecorationImage类、applyBoxFit 函数,等等。
本文是一个总结,深入探讨了Flutter中BoxFit枚举的各个值及其在实际编程中的应用。BoxFit是一个关键的枚举,它描述了如何在BoxConstraints中对齐和调整Box,对于控制图像或其他可绘制对象的尺寸和对齐方式具有重要作用。
文中首先详细解释了BoxFit的七个枚举值:fill、contain、cover、fitWidth、fitHeight、none和scaleDown,并通过实例说明了它们在实际应用中的效果和使用场景。
接着,本文介绍了BoxFit在各种Flutter组件中的应用,包括FittedBox、Image、RawImage、FadeInImage和DecorationImage。这些组件在Flutter开发中非常常见,理解和掌握BoxFit的使用,可以帮助开发者更好地控制这些组件的显示效果。
本文也简单介绍了applyBoxFit函数。该函数是Flutter中painting库的一部分,它用于应用BoxFit枚举值。虽然在大多数情况下,开发者不需要直接使用这个函数,但在创建自定义的绘图代码,或者需要手动处理图像或其他可绘制对象的尺寸和对齐方式时,这个函数会非常有用。
此外,本文还介绍了如何在Rive库中使用BoxFit。Rive是一个用于制作动画以及相关交互效果的库,BoxFit在其中也发挥了重要作用。本文详细介绍了RiveAnimation.network、RiveAnimation.asset、RiveAnimation.file和RiveAnimation.memory的使用方法,帮助开发者在使用Rive库时,能够更好地控制动画的显示效果。
作为子组件,会被拉伸填充满父组件,这可能会导致图像变形,因为宽度和高度方向的拉伸比例可能不同。
BoxFit.fill会拉伸子组件以完全填充父组件,这可能会导致子组件的宽高比被改变,因此可能会导致图像变形。这是因为宽度和高度方向的拉伸比例可能不同。这种方式不考虑子组件的宽高比,只关心父组件的空间,尽可能地填充满父组件的全部空间。
例如,如果你有一个正方形的空间,但是你的图像是一个长方形,那么使用BoxFit.fill,图像会被拉伸或压缩以填充整个正方形的空间,这可能会导致图像看起来扁平或过高。
BoxFit.contain是按原始比例缩放图像,使图像尽可能大,同时确保图像完全位于目标框内。这可能会导致目标框的一部分空间没有被图像填充。
BoxFit.cover是按原始比例缩放图像,使图像尽可能大,同时确保目标框完全被图像覆盖。
BoxFit.fitWidth是按原始比例缩放图像,使图像的宽度与目标框的宽度相等。
BoxFit.fitHeight是按原始比例缩放图像,使图像的高度与目标框的高度相等。
BoxFit.none是不对图像进行任何缩放,图像将会以其原始大小显示。
BoxFit.scaleDown的行为与BoxFit.contain相同,但是它不会放大图像。
FittedBox 组件根据fit属性的值来缩放和定位其子Widget。其构造函数为:
FittedBox({
Key? key,
BoxFit fit = BoxFit.contain,
AlignmentGeometry alignment = Alignment.center,
Clip clipBehavior = Clip.none,
Widget? child
})
其中:
例如:
class FittedBoxExample extends StatelessWidget {
const FittedBoxExample({super.key});
Widget build(BuildContext context) {
return Container(
height: 400,
width: 300,
color: Colors.blue,
child: const FittedBox(
fit: BoxFit.fill,
child: Placeholder(),
),
);
}
}
fill | cover | contain |
---|---|---|
fitWidth | fitHeight | none | scaleDown |
---|---|---|---|
Image是Flutter中的一个Widget,用于显示图像。它有多个构造函数,可以用于从不同的源加载图像。大多数构造函数都接受一个fit参数,这个参数是一个BoxFit枚举值,用于控制图像如何适应其当前分配的空间。
以下是Image的一些主要构造函数:
Image.asset(
'graphics/background.png',
fit: BoxFit.fill,
)
Image.network(
'https://example.com/graphics/background.png',
fit: BoxFit.cover,
)
Image.file(
File('/path/to/your/image.png'),
fit: BoxFit.scaleDown,
)
Image.memory(
bytes,
fit: BoxFit.contain,
)
在所有这些构造函数中,fit参数都是可选的。如果你不提供一个fit值,那么图像将会按照其原始尺寸显示,如果图像的尺寸大于其父Widget的尺寸,那么图像将会被剪裁。如果你提供了一个fit值,那么图像将会根据这个值来适应其父Widget。例如,如果你设置fit: BoxFit.cover,那么图像将会被缩放以完全覆盖其父Widget,可能会部分超出父Widget的范围。
RawImage组件直接显示一个 dart:ui.Image 对象。这个组件主要用于在你需要直接处理 dart:ui.Image** 对象时使用,例如你从一个自定义的图像解码器获取了图像,或者你从一个原生插件获取了图像。
RawImage 组件使用 paintImage函数 来绘制图像,这个函数提供了对这个类上的各个字段的详细解释。
值得注意的是,RawImage 不会处理图像的释放。当你不再需要 RawImage 时,你需要手动调用 Image.dispose 来释放图像资源。
在大多数情况下,你不需要直接使用 RawImage。如果你只是需要显示一个图像,那么使用 Image组件会更简单,因为Image组件提供了从各种源(如网络、文件、资源等)加载图像的功能。但是,如果你需要更底层的控制,或者你需要处理 dart:ui.Image对象,那么RawImage可能会用到。
RawImage的构造函数为:
const RawImage(
Key? key,
Image? image, // 要显示的图像,这是一个dart:ui.Image对象
String? debugImageLabel, // 图像的描述标签,仅在调试模式下使用
double? width, // 图像的宽度,如果为空,则图像的原始宽度将被使用
double? height, // 图像的高度,如果为空,则图像的原始高度将被使用
double scale = 1.0, // 图像的缩放比例
Color? color, // 与图像混合的颜色
Animation<double>? opacity, // 图像的不透明度,范围从0.0(完全透明)到1.0(完全不透明)
BlendMode? colorBlendMode, // 用于控制颜色如何与图像混合的模式
BoxFit? fit, // 图像的适应模式,用于控制图像如何适应其当前分配的空间
AlignmentGeometry alignment = Alignment.center, // 图像在其父widget中的对齐方式
ImageRepeat repeat = ImageRepeat.noRepeat, // 图像的重复模式,例如,如果图像小于其分配的空间,那么图像可以重复以填充空间
Rect? centerSlice, // 图像的中心切片,用于控制图像如何被拉伸
bool matchTextDirection = false, // 图像是否应根据当前的文本方向进行翻转
bool invertColors = false, // 图像的颜色是否应被反转
FilterQuality filterQuality = FilterQuality.low, // 图像的过滤质量
bool isAntiAlias = false // 图像是否应使用抗锯齿渲染
)
可见,与 Image 组件一样,RawImage组件也有一个fit 属性。一个示意用法的例子如下:
RawImage(
image: image, // dart:ui.Image对象
scale: 1.0,
width: 100.0,
height: 200.0,
color: Colors.red,
colorBlendMode: BlendMode.modulate,
fit: BoxFit.cover,
)
FadeInImage 组件 类似于 Image 组件。FadeInImage 组件在目标图像加载时显示一个 占位符图像,然后在图像加载完成时 通过淡入动画显示新图像。
这个类非常适合用于 显示加载时间较长的图像,例如网络图像,因为它可以让图像以优雅的动画效果出现在屏幕上,而不是突然出现。
FadeInImage还提供了一些属性来控制动画的行为,例如fadeOutDuration和fadeOutCurve用于控制占位符的淡出动画,fadeInDuration和fadeInCurve用于控制目标图像的淡入动画。
FadeInImage({
Key? key,
required ImageProvider<Object> placeholder, // 占位符图像
ImageErrorWidgetBuilder? placeholderErrorBuilder, // 占位符图像加载错误时的回调
required ImageProvider<Object> image, // 目标图像
ImageErrorWidgetBuilder? imageErrorBuilder, // 目标图像加载错误时的回调
bool excludeFromSemantics = false, // 是否从语义树中排除此图像
String? imageSemanticLabel, // 图像的语义标签
Duration fadeOutDuration = const Duration(milliseconds: 300), // 占位符图像淡出的持续时间
Curve fadeOutCurve = Curves.easeOut, // 占位符图像淡出的曲线
Duration fadeInDuration = const Duration(milliseconds: 700), // 目标图像淡入的持续时间
Curve fadeInCurve = Curves.easeIn, // 目标图像淡入的曲线
double? width, // 图像的宽度
double? height, // 图像的高度
BoxFit? fit, // 目标图像的适应模式
BoxFit? placeholderFit, // 占位符图像的适应模式
FilterQuality filterQuality = FilterQuality.low, // 目标图像的过滤质量
FilterQuality? placeholderFilterQuality, // 占位符图像的过滤质量
AlignmentGeometry alignment = Alignment.center, // 图像的对齐方式
ImageRepeat repeat = ImageRepeat.noRepeat, // 图像的重复模式
bool matchTextDirection = false // 图像是否应根据当前的文本方向进行翻转
})
其 fit 属性的含义与用法与之前相同,不再赘述。
FadeInImage.assetNetwork({
Key? key, // Widget的标识符
required String placeholder, // 占位符图像的资源名称
ImageErrorWidgetBuilder? placeholderErrorBuilder, // 占位符图像加载错误时的回调
required String image, // 目标图像的URL
ImageErrorWidgetBuilder? imageErrorBuilder, // 目标图像加载错误时的回调
AssetBundle? bundle, // 用于加载占位符图像的资源包
double? placeholderScale, // 占位符图像的缩放比例
double imageScale = 1.0, // 目标图像的缩放比例
bool excludeFromSemantics = false, // 是否从语义树中排除此图像
String? imageSemanticLabel, // 图像的语义标签
Duration fadeOutDuration = const Duration(milliseconds: 300), // 占位符图像淡出的持续时间
Curve fadeOutCurve = Curves.easeOut, // 占位符图像淡出的曲线
Duration fadeInDuration = const Duration(milliseconds: 700), // 目标图像淡入的持续时间
Curve fadeInCurve = Curves.easeIn, // 目标图像淡入的曲线
double? width, // 图像的宽度
double? height, // 图像的高度
BoxFit? fit, // 目标图像的适应模式
BoxFit? placeholderFit, // 占位符图像的适应模式
FilterQuality filterQuality = FilterQuality.low, // 目标图像的过滤质量
FilterQuality? placeholderFilterQuality, // 占位符图像的过滤质量
AlignmentGeometry alignment = Alignment.center, // 图像的对齐方式
ImageRepeat repeat = ImageRepeat.noRepeat, // 图像的重复模式
bool matchTextDirection = false, // 图像是否应根据当前的文本方向进行翻转
int? placeholderCacheWidth, // 占位符图像的缓存宽度
int? placeholderCacheHeight, // 占位符图像的缓存高度
int? imageCacheWidth, // 目标图像的缓存宽度
int? imageCacheHeight // 目标图像的缓存高度
})
其 fit 属性的含义与用法与之前相同,不再赘述。
FadeInImage.memoryNetwork({
Key? key, // Widget的标识符
required Uint8List placeholder, // 占位符图像的字节
ImageErrorWidgetBuilder? placeholderErrorBuilder, // 占位符图像加载错误时的回调
required String image, // 目标图像的URL
ImageErrorWidgetBuilder? imageErrorBuilder, // 目标图像加载错误时的回调
double placeholderScale = 1.0, // 占位符图像的缩放比例
double imageScale = 1.0, // 目标图像的缩放比例
bool excludeFromSemantics = false, // 是否从语义树中排除此图像
String? imageSemanticLabel, // 图像的语义标签
Duration fadeOutDuration = const Duration(milliseconds: 300), // 占位符图像淡出的持续时间
Curve fadeOutCurve = Curves.easeOut, // 占位符图像淡出的曲线
Duration fadeInDuration = const Duration(milliseconds: 700), // 目标图像淡入的持续时间
Curve fadeInCurve = Curves.easeIn, // 目标图像淡入的曲线
double? width, // 图像的宽度
double? height, // 图像的高度
BoxFit? fit, // 目标图像的适应模式
BoxFit? placeholderFit, // 占位符图像的适应模式
FilterQuality filterQuality = FilterQuality.low, // 目标图像的过滤质量
FilterQuality? placeholderFilterQuality, // 占位符图像的过滤质量
AlignmentGeometry alignment = Alignment.center, // 图像的对齐方式
ImageRepeat repeat = ImageRepeat.noRepeat, // 图像的重复模式
bool matchTextDirection = false, // 图像是否应根据当前的文本方向进行翻转
int? placeholderCacheWidth, // 占位符图像的缓存宽度
int? placeholderCacheHeight, // 占位符图像的缓存高度
int? imageCacheWidth, // 目标图像的缓存宽度
int? imageCacheHeight // 目标图像的缓存高度
})
其 fit 属性的含义与用法与之前相同,不再赘述。
DecorationImage 是 Flutter中的一个类,它用于在装饰(如BoxDecoration)中显示图像,以配置如何在装饰中绘制图像的。
它不是一个 Widget。
DecorationImage({
required ImageProvider<Object> image, // 要显示的图像,这是一个ImageProvider对象,例如AssetImage、NetworkImage等。
ImageErrorListener? onError, // 加载图像时发生错误的回调函数。
ColorFilter? colorFilter, // 应用于图像的颜色过滤器。
BoxFit? fit, // 图像的适应模式,用于控制图像如何适应其分配的空间。
AlignmentGeometry alignment = Alignment.center, // 图像在装饰中的对齐方式。
Rect? centerSlice, // 图像的中心切片,用于控制图像如何被拉伸。
ImageRepeat repeat = ImageRepeat.noRepeat, // 图像的重复模式,例如,如果图像小于其分配的空间,那么图像可以重复以填充空间。
bool matchTextDirection = false, // 图像是否应根据当前的文本方向进行翻转。
double scale = 1.0, // 图像的缩放比例。
double opacity = 1.0, // 图像的不透明度,范围从0.0(完全透明)到1.0(完全不透明)。
FilterQuality filterQuality = FilterQuality.low, // 图像的过滤质量。
bool invertColors = false, // 图像的颜色是否应被反转。
bool isAntiAlias = false // 图像是否应使用抗锯齿渲染。
})
例如,下面的代码展示了其用法。
BoxDecoration(
image: DecorationImage(
image: AssetImage('graphics/background.png'), // 从应用的资源目录中加载图像
fit: BoxFit.cover, // 图像会被缩放以完全覆盖其父Widget
),
)
其中, fit 参数也是 BoxFit 类型,用法与之前所述一致。
applyBoxFit函数是Flutter中painting库的一部分,它用于应用BoxFit枚举值。函数的定义如下:
FittedSizes applyBoxFit(
BoxFit fit,
Size inputSize,
Size outputSize
)
其中:
函数返回一个FittedSizes对象,它包含两个Size对象:source和destination。
这个函数不会对源尺寸和目标尺寸在输入和输出矩形中的对齐方式表达任何意见。通常,它们是居中的(这是BoxDecoration的行为,也是BoxFit的定义)。Alignment类提供了一个方便的函数Alignment.inscribe,用于将尺寸解析为矩形。
在大多数情况下,你不需要直接使用这个函数。但是,除非你正在创建自定义的绘图代码,或者需要手动处理图像或其他可绘制对象的尺寸和对齐方式时,才会用到。
以下是一个使用applyBoxFit函数的例子:
void paintImage(ui.Image image, Rect outputRect, Canvas canvas, Paint paint, BoxFit fit) {
final Size imageSize = Size(image.width.toDouble(), image.height.toDouble());
final FittedSizes sizes = applyBoxFit(fit, imageSize, outputRect.size);
final Rect inputSubrect = Alignment.center.inscribe(sizes.source, Offset.zero & imageSize);
final Rect outputSubrect = Alignment.center.inscribe(sizes.destination, outputRect);
canvas.drawImageRect(image, inputSubrect, outputSubrect, paint);
}
在这个例子中,我们首先获取图像的尺寸,然后使用 applyBoxFit 函数来计算源尺寸应该被缩放和对齐到的尺寸。然后,我们使用Alignment.center.inscribe函数来计算源尺寸和目标尺寸应该被绘制的矩形。最后,我们使用canvas.drawImageRect函数来绘制图像。
Rive 是一个用于制作动画以及相关交互效果的库。通常在里面制作好了相关的 .riv文件 ,从Rive软件导出后,作为静态资源放在 assets 目录中,或者将 .riv文件 放在一个静态文件服务器中。然后,通过 RiveAnimation 的不同构造方法在项目中使用。
当然,首先需要安装 rive
库:
flutter pub add rive
RiveAnimation.network 构造函数用于从网络加载Rive文件。例如:
RiveAnimation.network(
'https://example.com/myrivefile.riv',
fit: BoxFit.contain,
)
其中, fit 参数也是 BoxFit 类型,用法与之前所述一致。
RiveAnimation.asset:从项目的资源目录加载Rive文件。例如:
RiveAnimation.asset(
'assets/myrivefile.riv',
fit: BoxFit.contain,
)
其中, fit 参数也是 BoxFit 类型,用法与之前所述一致。
RiveAnimation.file:从设备的文件系统加载Rive文件。例如:
RiveAnimation.file(
File('/path/to/myrivefile.riv'),
fit: BoxFit.contain,
)
其中, fit 参数也是 BoxFit 类型,用法与之前所述一致。
RiveAnimation.memory:从内存加载Rive文件。例如:
RiveAnimation.memory(
bytes,
fit: BoxFit.contain,
)
其中,bytes是一个包含Rive文件数据的Uint8List。fit 参数也是 BoxFit 类型,用法与之前所述一致。
可见所有这些构造函数都接受一个fit参数,用于控制动画如何适应其分配的空间,以及一个alignment参数,用于控制动画在其分配的空间中的对齐方式。