使用 AspectRatio Widget

简介: 使用 AspectRatio Widget

image.png


AspectRatio widget 是用来约束宽高比例的,如果你需要 widget 必须要有一定的宽高比,这个组件就很有用。

但 AspectRatio 并不总是如你所愿,我一度想直接设置宽高达到同样的目的,但当你了解了它的逻辑之后,发现这样做并不明智,因为即使是直接设置高度,这些逻辑也是少不了的。

AspectRatio 需要父容器至少 width 或 height 是有边界的。

想想也是合理的。如果约束是没有边界的,而 AspectRatio 本身又没有宽高属性,AspectRatio 就无法设置宽高,只能都是无限,就和宽高有比例这个要求相矛盾。

AspectRatio 的尺寸的计算逻辑

  1. 如果父元素的宽高都没有边界,抛异常。
  2. 如果收到的是 tight 约束,那么相当于 AspectRatio 无效,不会起到任何作用,只会透传约束。
  3. 优先以宽度为准,按比例设置高度。如果宽度无限,以高度为准按比例设置宽度。
  4. 无论是高度还是宽度都必须在约束的范围内。

AspectRatio 的代码逻辑

决定宽高的代码

Size _applyAspectRatio(BoxConstraints constraints) {
    assert(constraints.debugAssertIsValid());
    assert(() {
      if (!constraints.hasBoundedWidth && !constraints.hasBoundedHeight) {
        throw FlutterError(
          '$runtimeType has unbounded constraints.\n'
          'This $runtimeType was given an aspect ratio of $aspectRatio but was given '
          'both unbounded width and unbounded height constraints. Because both '
          "constraints were unbounded, this render object doesn't know how much "
          'size to consume.',
        );
      }
      return true;
    }());
    if (constraints.isTight) {
      return constraints.smallest;
    }
    double width = constraints.maxWidth;
    double height;
    // We default to picking the height based on the width, but if the width
    // would be infinite, that's not sensible so we try to infer the height
    // from the width.
    if (width.isFinite) {
      height = width / _aspectRatio;
    } else {
      height = constraints.maxHeight;
      width = height * _aspectRatio;
    }
    // Similar to RenderImage, we iteratively attempt to fit within the given
    // constraints while maintaining the given aspect ratio. The order of
    // applying the constraints is also biased towards inferring the height
    // from the width.
    if (width > constraints.maxWidth) {
      width = constraints.maxWidth;
      height = width / _aspectRatio;
    }
    if (height > constraints.maxHeight) {
      height = constraints.maxHeight;
      width = height * _aspectRatio;
    }
    if (width < constraints.minWidth) {
      width = constraints.minWidth;
      height = width / _aspectRatio;
    }
    if (height < constraints.minHeight) {
      height = constraints.minHeight;
      width = height * _aspectRatio;
    }
    return constraints.constrain(Size(width, height));
  }
复制代码

定好自己的宽高后,把 child 设置成和自己一样宽高

@override
  void performLayout() {
    size = computeDryLayout(constraints);
    if (child != null) {
      child!.layout(BoxConstraints.tight(size));
    }
  }
复制代码

AspectRatio 的 renderObject 继承自 RenderProxyBox。只可以有一个child,没有 alignment 属性,不能摆放 child的位置。

AspectRatio 的 aspectRatio 参数要求是 大于0 的 double ,但是一般都是用分数的形式来写,这样可读性会更好些。

AspectRatio(
      aspectRatio: 1 / 2,
);


目录
相关文章
|
API Android开发
CardView的那点事儿
CardView的那点事儿
141 0
|
缓存
【布局 widget】Flutter ListView
ListView 是最常用的滚动 widget,也是布局 widget。它在滚动方向上一个接一个地显示它的 child。
265 0
【布局 widget】Flutter ListView
【布局 widget】 Flutter GridView
GridView 独有的参数其实只有一个 gridDelegate,gridDelegate 的作用是为 GridView 布局,制定每行几个 child,空白多少等。
164 0
【布局 widget】 Flutter GridView
|
前端开发 容器
【布局 widget】OverflowBox 与 SizedOverflowBox
【布局 widget】OverflowBox 与 SizedOverflowBox
151 0
【布局 widget】OverflowBox 与 SizedOverflowBox
【布局 widget】ConstrainedBox 与 UnconstrainedBox
【布局 widget】ConstrainedBox 与 UnconstrainedBox
168 0
【布局 widget】ConstrainedBox 与 UnconstrainedBox
【布局 widget】Offstage 与 Visibility
【布局 widget】Offstage 与 Visibility
134 0
【布局 widget】Offstage 与 Visibility
RecyclerView与CardView的使用(二)
RecyclerView与CardView的使用(二)
139 0
RecyclerView与CardView的使用(二)
|
开发工具 Android开发
RecyclerView与CardView的使用(一)
RecyclerView与CardView的使用(一)
175 0
RecyclerView与CardView的使用(一)
|
缓存 Dart
Flutter一切皆widget但是不要将所有东西放入一个widget
当我们在widgets目录中,我们可以看到很多小部件,如Padding,Align,SizedBox,等。我们通过组合它们来创建其他小部件,我发现这种方法可扩展、强大且易于理解。 但是当我阅读 一些我在互联网上找到的或由新采用者编写的源代码时,有一件让我震惊的事情:拥有大量build ` 方法的趋势,实例化很多小部件!我发现这很难阅读、理解和维护。
106 0
|
Android开发
2-VVI-材料设计之CardView
零、前言 [1].CardView extends FrameLayout [2].一个带圆角和阴影的FrameLayout,FrameLayout怎么用,它就怎么用 [3].
1140 0