写点什么

flutter 系列之: 按比例缩放的 AspectRatio 和 FractionallySizedBox

作者:程序那些事
  • 2022 年 6 月 18 日
  • 本文字数:2050 字

    阅读完需:约 7 分钟

简介

我们在构建 UI 的时候,为了适应不同的屏幕大小,通常需要进行一些自适应的配置,而最常见的自适应就是根据某个宽度或者高度自动进行组件的缩放。


今天要给大家介绍两个可以自动缩放的组件 AspectRatio 和 FractionallySizedBox。

AspectRatio

AspectRatio 的目的就是将其 child 按比例缩放。


先来看下 AspectRatio 的定义:


class AspectRatio extends SingleChildRenderObjectWidget
复制代码


可以看到 AspectRatio 继承自 SingleChildRenderObjectWidget,表示用来呈现一个 single child。


AspectRatio 需要的属性有两个,分别是 aspectRatio 和子元素 child。


aspectRatio 是一个 double 类型的数据,为了方便起见,我们一般使用比例的格式来进行表示,比如 3.0/2.0 等。


虽然我们知道 3/2 的结果是 1.5,但是我们最好不要自行计算结果,因为使用 3.0/2.0 更加直观。


AspectRatio 的逻辑是首先获得最大的 width 或者 height,然后根据 width 或者 height 来计算 height 和 width。接下来我们来看几个具体的例子,来详细了解 AspectRatio。


首先是一个无限宽度但是高度为 150 的 container,然后再 container 的 child 中使用了 AspectRatio 组件,如下所示:


  Widget build(BuildContext context) {    return Container(      color: Colors.blue,      alignment: Alignment.center,      width: double.infinity,      height: 150.0,      child: AspectRatio(        aspectRatio: 3 / 2,        child: Container(          color: Colors.red,        ),      ),    );
复制代码


这里的 aspectRatio=3/2, 那么怎么来计算 aspectRatio 的大小呢?


对于 aspectRatio 的父 widget 来说,他的宽度是无限的,他的高度是 150,所以 aspectRatio 的高度是可以确定的,也就是 150,我们根据 aspectRatio 的比例,计算出它的 width=150/2 * 3 = 225, 如下所示:



再看下面的一个例子:


  Widget build(BuildContext context) {    return Container(      color: Colors.blue,      alignment: Alignment.center,      width: 150.0,      height: 150.0,      child: AspectRatio(        aspectRatio: 2.0,        child: Container(          color: Colors.red,        ),      ),    );  }
复制代码


这个例子中 Container 的 width 和 height 是相等的。


在它的 child 中使用的 aspectRatio=2.0。如果 child 的 height 选择=150,那么对应的 width 就应该是 300,很明显超出了 Container 的范围,所以这里选择的是 width=150, 而对应的 height=75, 入下图所示:



那么问题来了, 如果 AspectRatio 指定了大小应该怎么处理呢?


比如我们给 aspectRatio 的 child 添加一个 width 和 height 限制:


  Widget build(BuildContext context) {    return Container(      color: Colors.blue,      alignment: Alignment.center,      width: 150.0,      height: 150.0,      child: AspectRatio(        aspectRatio: 2.0,        child: Container(          color: Colors.red,          width: 50,          height: 50,        ),      ),    );  }
复制代码


你会发现这个 width 和 height 对 Container 的大小是没有效果的。


这里就要谈到之前我们提到的 constraints 了,对于 AspectRatio 来说,他希望子 child 填充满它的空间,所以 child 会继承这个 constraints,从而展示相同的界面。

FractionallySizedBox

FractionallySizedBox 和 AspectRatio 有些类似,不过 FractionallySizedBox 是按照可用空间的大小来进行比例设置的。


首先来看下 FractionallySizedBox 的定义:


class FractionallySizedBox extends SingleChildRenderObjectWidget
复制代码


可以看到 FractionallySizedBox 和 AspectRatio 一样继承自 SingleChildRenderObjectWidget。


FractionallySizedBox 有三个属性,分别是 alignment,widthFactor 和 heightFactor。


其中 alignment 表示的是 FractionallySizedBox 中子 child 的排列方式。


而 widthFactor 和 heightFactor 是 double 类型的,表示的是对应的缩放比例。


接下来,我们看一下 FractionallySizedBox 的具体使用。


  Widget build(BuildContext context) {
return FractionallySizedBox( widthFactor: 1, heightFactor: 0.25, alignment: FractionalOffset.center, child: DecoratedBox( decoration: BoxDecoration( border: Border.all( color: Colors.red, width: 4, ), ), ), ); }
复制代码


这里我们设置对应的 widthFactor=1 和 heightFactor=0.25, 也就是说 widht 和可用空间的 width 是一致的,而 height 只有原来的 1/4。


为了方便起见,我们将 child 用一个 DecoratedBox 封装起来,用来展示 box 的边界,最后得到的界面如下所示:


总结

熟练使用 AspectRatio 和 FractionallySizedBox 可以很方便的按比例来绘制界面的元素,非常好用。


本文的例子:https://github.com/ddean2009/learn-flutter.git


更多内容请参考 www.flydean.com

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 刚刚阅读数: 4
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
flutter系列之:按比例缩放的AspectRatio和FractionallySizedBox_flutter_程序那些事_InfoQ写作社区