乐趣区

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

简介

咱们在构建 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

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

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

退出移动版