注册

Flutter 组件分析之AspectRatio

引言


AspectRatio 可以根据具体的长宽比约束 child 的布局范围, 从而影响 child 的大小. 通常在视频、图像中会经常使用, 今天我们来分析一下它的实现原理.


AspectRatio


AspectRatio 的参数只有 key、aspectRatio、child. 它会根据 aspectRatio 去重计算约束 child 的布局范围.
image
我们举一个例子:


    Center(
child: AspectRatio(
aspectRatio: 1.0,
child: Image.network('xx'),
),
)

以图片长宽比3:2为例子




  • 当 aspectRatio 为1.0时:

    由于图片的比例大于 1.0, aspectRatio 取 1.0 时, 以屏宽为基准, 1:1为比例, 构建了一个正方形的布局约束范围. 当图片比大于 1.0 时, 图片以屏宽为图片宽, 而图片高要小于约束高. 因此实际布局中, 图片在约束中央.


    image


  • 当 aspectRatio 为0.2时:

    由于图片的比例大于 1.0, aspectRatio 取 0.2 时, 屏幕宽高大于0.2. 以屏高为基准, 1:5为比例, 构建了一个矩形的布局约束范围. 当图片比大于 1.0 时, 图片以屏幕高的1/5为图片宽. 因此实际布局中, 图片会比正常小.


    image


  • 当 aspectRatio 为5.0时:

    由于图片的比例大于 1.0, aspectRatio 取 5.0 时, 屏幕宽高小于5.0. 以屏宽为基准, 5:1为比例, 构建了一个矩形的布局约束范围. 当图片比大于 1.0 时, 图片以屏幕高为图片的高. 因此实际布局中, 图片会比正常小.


    image


这一系列的原因都来自于内部的算法, 让我们一起进入源码中学习一下~


RenderAspectRatio


RenderAspectRatio 是 AspectRatio 的 RenderObject . 里面也封装了关于布局的计算规则, AspectRatio 的计算核心在于 _applyAspectRatio.


constraints.isTight


如果尺寸刚刚好合适的话, 会返回满足约束的最小大小

image.png


非constraints.isTight


这种情况下, width 会拥有默认赋值. 首先会等于约束的最大宽度. 如果宽度是有限的, 那么高度会根据 _aspectRatio 赋值. 反之, 高度会取约束限制的最大高, 同时将宽根据高度重赋值.在赋值完基础度宽高后, 会通过四个判断获取最后的尺寸.
image




四个判断如下:



  • width > constraints.maxWidth

    当宽度大于约束最大宽时, 会重新把宽赋值为约束的最大宽, 并重计算高
  • height > constraints.maxHeight

    当高度大于约束最大高时, 会重新把高赋值为约束的最大高, 并重计算宽
  • width < constraints.minWidth

    当宽小于约束的最小值时, 会把宽赋值为约束度最小值, 并重计算高
  • height < constraints.minHeight

    当高小于约束的最小值时, 会把高赋值为约束度最小值, 并重计算宽

image

在经过这一系列计算后, 宽高将会根据 aspectRatio 重计算直至符合 aspectRatio 并且能放进约束中.


作者:WeninerIo
链接:https://juejin.cn/post/7177559990805217340
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册