Flutter 约束宽高比的控件 AspectRatio

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

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

是动态设置?仍是写死宽高?express

为此,Flutter 为咱们提供了能够约束宽高比的控件 AspectRatioapp

基本操做

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

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

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 首先尝试布局约束所容许的最大宽度。经过给定的宽高比来肯定小部件的高度,表示为宽度与高度的比率。ui

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

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,咱们看一下样式:

WX20190530-202614@2x

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

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

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

相关文章
相关标签/搜索