8 宽高尺寸处理

对组件具体尺寸的设置有多种方式,本节将详述这类组件。

8.1 SizedBox(设置具体尺寸)

SizedBox组件是一个特定大小的盒子,这个组件强制它的child有特定的宽度和高度。如果宽度或高度为null,则此组件将调整自身大小以匹配该维度中child的大小。 SizedBox组件的主要属性如下所示: 接下来我们写个例子,添加一个SizedBox容器,在它里面放一个Card,那么Card就被限定在宽200、高300的范围内。完整的示例代码如下:

import 'package:flutter/material.dart';

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('SizedBox设置具体尺寸示例'),
      ),
      body: SizedBox(
        //固定宽为200.0,高为300.0
        width: 200.0,
        height: 300.0,
        child: const Card(
            child: Text('SizedBox',
              style: TextStyle(
                fontSize: 36.0,
              ),
            )),
      ),
    );
  }
}

void main() {
  runApp(
    new MaterialApp(
      title: 'OverflowBox溢出父容器显示示例',
      home: new LayoutDemo(),
    ),
  );
}

上述示例代码的视图展现大致如图7-28所示。

8.2 ConstrainedBox(限定最大最小宽高布局)

ConstrainedBox的作用是限定子元素child的最大宽度、最大高度、最小宽度和最小高度。ConstrainedBox主要属性如下所示: 接下来我们写一个小示例,示例中在一个宽高为300.0的Container上添加一个约束最大最小宽高的ConstrainedBox,实际显示中,则是一个宽高为220.0的区域。示例代码如下:

import 'package:flutter/material.dart';
class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('ConstrainedBox限定宽高示例'),
      ),
      body: new ConstrainedBox(
        constraints: const BoxConstraints(
          minWidth: 150.0,
          minHeight: 150.0,
          maxWidth: 220.0,
          maxHeight: 220.0,
        ),
        child: new Container(
          width: 300.0,
          height: 300.0,
          color: Colors.green,
        ),
      ),
    );
  }
}
void main() {
  runApp(
    new MaterialApp(
      title: 'ConstrainedBox限定宽高示例',
      home: new LayoutDemo(),
    ),
  );
}

上述示例代码的视图展现大致如图7-29所示。

8.3 LimitedBox(限定最大宽高布局)

LimitedBox组件是限制类型的组件,可对最大宽高进行限制。和ConstrainedBox类似,只不过LimitedBox组件没有最小宽高限制。 从布局的角度讲,LimitedBox是将child限制在其设定的最大宽高中的,但这个限定是有条件的。当LimitedBox最大宽度不受限制时,child的宽度就会受到这个最大宽度的限制,高度同理。LimitedBox组件的主要属性如下所示: 接下来我们写一个小示例,添加两个容器,第一个容器宽度为100,高度撑满父容器。第二个容器虽然宽度设置为250,但是由于它的父容器用LimitedBox限定的最大宽度为150,所以它的实际宽度为150,高度也同样撑满父容器。完整的示例代码如下:

import 'package:flutter/material.dart';
class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('LimitedBox限定宽高布局示例'),
        ),
        body: Row(
          children: <Widget>[
            Container(
              color: Colors.grey,
              width: 100.0,
            ),
            LimitedBox(
              maxWidth: 150.0,//设置最大宽度,限定child在此范围内
              child: Container(
                color: Colors.lightGreen,
                width: 250.0,
              ),
            ),
          ],

        )
    );
  }
}
void main() {
  runApp(
    new MaterialApp(
      title: 'LimitedBox限定宽高布局示例',
      home: new LayoutDemo(),
    ),
  );
}   

上述示例代码的视图展现大致如图7-30所示。

8.4 AspectRatio(调整宽高比)

AspectRatio的作用是根据设置调整子元素child的宽高比,Flutter提供此组件,就免去了自定义所带来的麻烦。AspectRatio适用于需要固定宽高比的情景。 AspectRatio的布局行为分为两种情况: □AspectRatio首先会在布局限制条件允许的范围内尽可能地扩展,Widget的高度是由宽度和比率决定的,类似于BoxFit中的contain,按照固定比率去尽量占满区域。 □如果在满足所有限制条件后无法找到可行的尺寸,AspectRatio最终将会优先适应布局限制条件,而忽略所设置的比率。 AspectRatio主要属性如下所示: 接下来我们写一个小示例,示例代码定义了一个高度为200的区域,内部AspectRatio比率设置为1.5,最终AspectRatio是宽300高200的一个区域。示例代码如下:

import 'package:flutter/material.dart';
class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('AspectRatio调整宽高比示例'),
      ),
      body: new Container(
        height: 200.0,
        child: new AspectRatio(
          aspectRatio: 1.5,//比例可以调整
          child: new Container(
            color: Colors.green,
          ),
        ),
      ),
    );
  }
}
void main() {
  runApp(
    new MaterialApp(
      title: 'AspectRatio调整宽高比',
      home: new LayoutDemo(),
    ),
  );
}

上述示例代码的视图展现大致如图7-31所示。

8.5 FractionallySizedBox(百分比布局)

FractionallySizedBox组件会根据现有空间来调整child的尺寸,所以就算为child设置了具体的尺寸数值,也不起作用。当需要在一个区域里面取百分比尺寸时,可以使用这个组件,比如需要一个高度30%宽度60%的区域。 FractionallySizedBox的布局主要跟它的宽高因子(两个参数)有关,当参数为null或者有具体数值的时候,布局表现不一样。当然,还有一个辅助参数alignment,作为对齐方式进行布局。具体有以下两种情况: □设置了具体的宽高因子,具体的宽高则根据现有空间宽高×因子,当宽高因子大于1的时候,有可能会超出父组件的范围。 □没有设置宽高因子,则填满可用区域。 FractionallySizedBox组件的主要属性如下所示: 接下来我们写一个小示例,示例中有两个容器,底部的容器宽高各为200。如果上面的容器宽度因子为0.5,则它的实际宽度为100;如果高度因子为1.5,则它的实际高度为300。对齐方式为左上角对齐。所以上层的元素横向在容器内部,纵向已经超出容器了。完整的示例代码如下:

import 'package:flutter/material.dart';
class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('FractionallySizedBox百分比布局示例'),
      ),
      body: new Container(
        color: Colors.blueGrey,
        height: 200.0,
        width: 200.0,
        child: new FractionallySizedBox(
          alignment: Alignment.topLeft,//元素左上角
                         对齐
          widthFactor: 0.5,//宽度因子
          heightFactor: 1.5,//高度因子
          child: new Container(
            color: Colors.green,
          ),
        ),
      ),
    );
  }
}
void main() {
  runApp(
    new MaterialApp(
      title: 'FractionallySizedBox百分比布局示例',
      home: new LayoutDemo(),
    ),
  );
}

上述示例代码的视图展现大致如图7-32所示。