关于flutter:flutter系列之深入理解布局的基础constraints

4次阅读

共计 3816 个字符,预计需要花费 10 分钟才能阅读完成。

简介

咱们在 flutter 中应用 layout 的时候须要常常对组件进行一些大小的限度,这种限度就叫做 constraints,用来管制 layout 中的组件大小。

把握了 constraints 才算对 layout 有了真正的理解,然而 flutter 中的 constraints 和咱们相熟的 HTML 中的 constraints 区别比拟大,所以咱们还是须要深刻理解 flutter 中 contraints 的个性。

Tight 和 loose constraints

对于 constraints 来说,只有四个属性,别离是最小 width,最大 width,最小 height 和最大 height。这四个属性所能限度的就是宽度和高度的范畴。

依据这两个属性的范畴不同,constraints 能够分为 tight constraints 和 loose constraints。

那么 tight 和 loose 有什么区别呢?

对于 tight 来说,它的 maximum width = minimum width, 并且 maximum height = minimum height, 也就是说为 width 和 height 提供了一个特定的值。

具体而言,能够看下 BoxConstraints 的 tight 实现:

BoxConstraints.tight(Size size)
   : minWidth = size.width,
     maxWidth = size.width,
     minHeight = size.height,
     maxHeight = size.height;

和 tight 绝对应的就是 loose,在 loose 中咱们设置了最大的 width 和 height, 然而心愿 widget 越小越好,这样对应 width 和 height 的最小值为 0,同样以 BoxConstraints 为例看下它的定义:

BoxConstraints.loose(Size size)
   : minWidth = 0.0,
     maxWidth = size.width,
     minHeight = 0.0,
     maxHeight = size.height;

了解 constraints 的准则

后面咱们讲到了 constraints 的分类,这里咱们会讲一下 constraints 的根本准则。

通常来说,在 flutter 中,一个 widget 的 constraints 是从它的 parent 继承而来的。而后这个 widget 会将 constraints 通知他的子 widget.

子 widget 会有本人定义的大小,那么子 widget 会依据本人定义的大小来设置本人的大小,并将后果反馈跟父 widget,父 widget 会最终依据所有子 widget 的大小来设置本人的大小。

所以总结而言就是,constraints 是向下传递的,而 size 是向上传递的。

可能大家还不太明确是什么意思,没关系,接下来咱们用具体的例子来阐明。

首先,咱们应用 BoxConstraints.tightFor 来创立一个尽可能大的 width 和 height 的 Constraints, 而后在这个 constraint 外部新建 widget 来察看他们的体现。

ConstrainedBox(
     constraints: const BoxConstraints.tightFor(width: double.infinity, height: double.infinity),
            child: exampleWidget)

通过替换下面的 exampleWidget,咱们来察看不同的表现形式。

首先是最根底的 Container,对于 Container 自身来说,他能够设置 width 和 height, 然而这两个属性并不是 constraint,所以还得从 parent widget 中继承。

那么对于上面的一个 widget 来说:

  Widget build(BuildContext context) {return Container(color: blue);
  }

它会应用从 parent 继承的 constraints, 也就是说尽可能的大,所以会展现上面的界面:

填满所有的区域。

如果给 Container 指定了 width 和 hight,同样的,Container 须要从 parent 继承 constraints, 所以依然是填满整个区域:

  Widget build(BuildContext context) {return Container(width: 100, height: 100, color: blue);
  }

然而,如果咱们在 Container 的里面再加上一个 constraints, 比方 Center:

  Widget build(BuildContext context) {
    return Center(child: Container(width: 100, height: 100, color: blue),
    );
  }

那么尽管 Center 会从 parent 继承 constraints,去填满整个区域,然而 Center 自身的 constraints 是通知子 widget 能够依照他本人的志愿来调整大小,所以这个时候最终 Container 的大小就是 100×100:

除了 Center 之外,咱们还能够应用 Align,成果和 Center 是统一的:

  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.bottomLeft,
      child: Container(width: 100, height: 100, color: blue),
    );
  }

上面是一个应用 Center 的很乏味的例子:

  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: blue,
        child: Container(color: green, width: 30, height: 30),
      ),
    );
  }

这里 Center 中有一个 Container,Container 中有一个 Container,然而这两个 Container 设置了不同的色彩。

因为外层的 Container 并没有设置大小,所以他的大小是由 child Container 来决定的,因为两个 Container 大小一样,所以内部的色彩会被外部的笼罩,咱们能够失去上面的界面:

如果咱们给外层的增加一个 padding 如下:

  Widget build(BuildContext context) {
    return Center(
      child: Container(padding: const EdgeInsets.all(20.0),
        color: blue,
        child: Container(color: green, width: 30, height: 30),
      ),
    );
  }

那么外层当初就比内层的 widget 要大了,色彩也能够展现进去了:

咱们再来看上面的例子:

  Widget build(BuildContext context) {
    return ConstrainedBox(
      constraints: const BoxConstraints(
        minWidth: 70,
        minHeight: 70,
        maxWidth: 150,
        maxHeight: 150,
      ),
      child: Container(color: blue, width: 10, height: 10),
    );
  }

下面的例子在 Container 里面增加了一个 ConstrainedBox,指定了四个 constraints 属性,然而这个 ConstrainedBox 并不会利用到 child 上,所以最终失去的界面还是全副的蓝色。

为什么呢?这是因为不同的 widget 对 constraints 有不同的定义,对于 ConstrainedBox 来说,他是一个对其子项施加额定束缚的小部件。记住,这里是额定的束缚。因为对于它的 parent 来说,束缚曾经制订好了,所以 ConstrainedBox 会被疏忽。

咱们再看下上面的代码:

  Widget build(BuildContext context) {
    return Center(
      child: ConstrainedBox(
        constraints: const BoxConstraints(
          minWidth: 70,
          minHeight: 70,
          maxWidth: 150,
          maxHeight: 150,
        ),
        child: Container(color: blue, width: 10, height: 10),
      ),
    );
  }

这里因为应用了 Center,Center 会让 child 来自行决定他们的大小,所以这里的 ConstrainedBox 是失效的,如下:

flutter 中除了 ConstrainedBox,还有一个 UnconstrainedBox, 它的作用和 ConstrainedBox 是相同的,大家能够自行尝试。

总结

从下面的具体例子,咱们能够看出,尽管咱们有通用的 Constraint 规定,然而具体的体现还是要看不同的 widget 来定。

所以大家在应用 widget 的时候,肯定要去读一下 widget 的代码,从而加深对 widget 的把握。

本文的例子:https://github.com/ddean2009/learn-flutter.git

更多内容请参考 http://www.flydean.com/13-flutter-ui-constraints/

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

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

正文完
 0