Flutter 约束宽高比的控件 AspectRatio

在搭建 UI 的过程中,经常会出现要求约束宽高比的需求。

比如,把照片变成 16:9 或者 4:3 ,这个时候你会怎么做?

是动态设置?还是写死宽高?

为此,Flutter 为我们提供了可以约束宽高比的控件 AspectRatio

基本操作

还是按照惯例,先看官方文档:

A widget that attempts to size the child to a specific aspect ratio.

The widget first tries the largest width permitted by the layout constraints. The height of the widget is determined by applying the given aspect ratio to the width, expressed as a ratio of width to height.

尝试将子项调整为特定宽高比的 widget。

widget 首先尝试布局约束所允许的最大宽度。通过给定的宽高比来确定小部件的高度,表示为宽度与高度的比率。

还是一样没有demo,不过这种控件使用起来是比较简单的,直接来看构造函数:

const AspectRatio({
  Key key,
  @required this.aspectRatio,
  Widget child,
}) : assert(aspectRatio != null),
super(key: key, child: child);
复制代码

构造函数非常简单,只需要一个 宽高比 和一个 child。

撸码前有个点要注意一下,文档上面说了, 该widget 首先会尝试布局约束所允许的最大宽度。

也就是说,直接放一个 AspectRatio 上去他就是最大宽度的。

鉴于此,我们写demo的时候要先限定一下它的宽度。

class AspectRatioPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AspectRatioPage'),
      ),
      body: Center(
        child: Container(
          width: 300, // 限定一下宽度
          child: AspectRatio(
            aspectRatio: 16.0 / 9.0, // 设置宽高比为16:9
            child: Image.asset(
              'images/game3.jpg',
              fit: BoxFit.cover, //需设置一下裁剪模式来查看效果
            ),
          ),
        ),
      ),
    );
  }
}
复制代码

效果如下:

把宽高比设置为4:3 看一下:

可以看到,确实是按照我们输入的比例来执行的。

与GridView 联动

我们可能遇到更多的需求是:在GridView 中,也要控制住每一张图片的宽高比。

如果没有AspectRatio 控件则比较难实现,因为要算间距之类的。

但是有了 AspectRatio,我们的代码就会简单很多,看一张动图:

可以看到,我们只需简单的更改宽高比,即可自动设置。

代码如下:

class AspectRatioPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AspectRatioPage'),
      ),
      body: Center(
        child: _createGridView(),
      ),
    );
  }

  Widget _createGridView() {
    return GridView.builder(
      itemCount: 6,
      shrinkWrap: true,
      padding: EdgeInsets.all(10), // padding
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3, // 每一行的个数
        mainAxisSpacing: 10, // 间距
        crossAxisSpacing: 10,
      ),
      itemBuilder: (context, index) {
        return Container(
          alignment: Alignment.center,
          child: AspectRatio(
            aspectRatio: 1, // 宽高比
            child: Image.asset(
              'images/game3.jpg',
              fit: BoxFit.cover,
            ),
          ),
        );
      },
    );
  }
}
复制代码

设置每一行为3个,间距为10,这时 Flutter 会自动给我们算出来我们控件的宽高。

这个时候我们就只需要设置宽高比即可设置合适的宽高。

设置不符合常理的宽高

前面我们设置的都是符合常理的宽高。

比如,我们限制了外部容器的宽高都为100。

第一种情况:宽高比为 2,设置宽为100,那么高会自动算出来为50,这样是合理的。

第二种情况:宽高比为0.5,也就是说高比宽更长,那这个时候我设置宽为100,会是什么样的结果?

正常来说,高应该为200,但是我们前面限定了宽高都为100。

这个时候AspectRatio会根据当前最高的值自动再计算一次宽高比,算出来宽应为50。

我们可以使用刚才的GridView 来实现这个猜想,因为GridView中的宽高就是限制好的。

看一下代码:

Widget _createGridView() {
  return GridView.builder(
    itemCount: 6,
    shrinkWrap: true,
    padding: EdgeInsets.all(10),
    // padding
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 3, // 每一行的个数
      mainAxisSpacing: 10, // 间距
      crossAxisSpacing: 10,
    ),
    itemBuilder: (context, index) {
      return Container(
        alignment: Alignment.center,
        child: AspectRatio(
          aspectRatio: 0.5, // 宽高比
          child: Image.asset(
            'images/game3.jpg',
            fit: BoxFit.cover,
          ),
        ),
      );
    },
  );
}
复制代码

这里只是把宽高比设置为了0.5,我们看一下样式:

可以看到,确实如刚才所说,把宽度变小了。

关注我,每天更新 Flutter & Dart 知识。

完整代码已经传至GitHub:github.com/wanglu1209/…

转载于:https://juejin.im/post/5cefce50f265da1bc14b0db3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值