Flutter - 布局原理与约束(constraints)

时间:2022-12-10 10:52:56

尺寸限制类容器用于限制容器大小,Flutter中提供了多种这样的容器,如ConstrainedBox、SizedBox、UnconstrainedBox、AspectRatio 等

1 ConstrainedBox
ConstrainedBox 用于对子组件添加额外的约束 一般作为最外层的父布局

2 BoxConstraints
BoxConstraints 为ConstrainedBox提供 基础的宽高限制

const BoxConstraints({
  this.minWidth = 0.0, //最小宽度
  this.maxWidth = double.infinity, //最大宽度
  this.minHeight = 0.0, //最小高度
  this.maxHeight = double.infinity //最大高度
})

示例 :
ConstrainedBox(
  constraints: BoxConstraints(
    minWidth: double.infinity, //宽度尽可能大
    minHeight: 46.0 //最小高度为46像素
  ),
  child: Container(
    height: 5.0, // 不起作用 ,以父容器的约束为准
    child: DecoratedBox(
           decoration: BoxDecoration(color: Colors.blue),
    ) ,
  ),
)

Flutter - 布局原理与约束(constraints)

同时 BoxConstraints 也定义有一些便捷的构造方法

1  BoxConstraints.tight(Size(100,100))  // 设置宽高为100 ,100 通过Size 设置

ConstrainedBox(
  constraints: BoxConstraints.tight(Size(60,80)),
  child: DecoratedBox(
    decoration: BoxDecoration(color: Colors.blue),
  ),
),

Flutter - 布局原理与约束(constraints)

2 BoxConstraints.tightFor(width: 80,height: 80)  // 设置最大值 和 最小值 都为80 ,80 

相当于 

BoxConstraints(minHeight: 80.0,maxHeight: 80.0,minWidth: 80.0,maxWidth: 80.0)
//可以生成一个尽可能大的用以填充另一个容器的BoxConstraints
3 BoxConstraints.expand(width: 100.0,height: 100.0), 

示例 :
ConstrainedBox(
  constraints: BoxConstraints.tightFor(width: 50,height: 50),// 最外围的约束是 宽 50  高 50
  child: ConstrainedBox(
      constraints: const BoxConstraints.expand(), // 可以生成一个尽可能大的用以填充另一个容器的BoxConstraints
      child: Container(
        height: 59,  // 不起作用 ,以父容器的约束为准
        width: 102,  // 不起作用 ,以父容器的约束为准
        child: DecoratedBox(
          decoration: BoxDecoration(color: Colors.red),
        ),
      ),
  ),
),

Flutter - 布局原理与约束(constraints)
3 SizedBox
SizedBox 用于给子元素指定固定的宽高

SizedBox(
  width: 80,
  height: 80,
  child: DecoratedBox(
    decoration: BoxDecoration(color: Colors.yellow),
  ),
),

Flutter - 布局原理与约束(constraints)
但SizedBox只是ConstrainedBox的一个简单用法,上面代码等价于:

ConstrainedBox(
  constraints: BoxConstraints.tightFor(width: 80.0,height: 80.0),
  child: DecoratedBox(
    decoration: BoxDecoration(color: Colors.yellow),
  ),
)

等价于


ConstrainedBox(
  constraints: BoxConstraints(minHeight: 80.0,maxHeight: 80.0,minWidth: 80.0,maxWidth: 80.0),
  child: DecoratedBox(
    decoration: BoxDecoration(color: Colors.yellow),
  ),
)

4 多重限制

有多个 父级限制, 会取两个限制值的最大的值

ConstrainedBox(
    constraints: BoxConstraints(minWidth: 60.0, minHeight: 60.0),  //父
    child: ConstrainedBox(
    constraints: BoxConstraints(minWidth: 5.0, minHeight: 80.0),//子
      child: DecoratedBox(
        decoration: BoxDecoration(color: Colors.orange),
      ),
    ),
),

Flutter - 布局原理与约束(constraints)
5 UnconstrainedBox
UnconstrainedBox 取消限制 子布局 可以取消父布局的限制 ,但 父布局仍占用空间

ConstrainedBox(
    constraints: BoxConstraints(minWidth: 90.0, minHeight: 20.0),
    child: ConstrainedBox(//多重布局限制
      constraints: BoxConstraints(minWidth: 60.0, minHeight: 60.0),
      child: DecoratedBox(//多重布局限制
        decoration: BoxDecoration(color: Colors.yellow),
        child: UnconstrainedBox(
          alignment: Alignment.topRight, // UnconstrainedBox 中控制子布局的位置
          child:
          SizedBox( // 取消限制的子布局
            width: 80,
            height: 20,
            child: DecoratedBox(
              decoration: BoxDecoration(color: Colors.red),
            )
          ),
        ),
      ),
    )
),

Flutter - 布局原理与约束(constraints)

6 AspectRatio
AspectRatio 使用时 是根据父空间的宽高比进行设置的 ,如果父布局有具体宽高则 AspectRatio 失效

ConstrainedBox(
    constraints: BoxConstraints(maxWidth: 90), // 创建一个宽度最大为90的约束
    // height: 100,
    child: AspectRatio( // 使用时 是根据父空间的宽高比进行设置的 ,如果父布局有具体宽高则 AspectRatio 失效
      aspectRatio: 3,
      child: Container(
        color: Colors.pink,
      ),
    ),
),

Flutter - 布局原理与约束(constraints)
LimitedBox 用于指定最大宽高
FractionallySizedBox 可以根据父容器宽高的百分比来设置子组件宽高

其他
Flutter - 布局原理与约束(constraints)

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

class MyConstrainedBoxState extends StatefulWidget {
  const MyConstrainedBoxState({Key? key}) : super(key: key);

  
  State<MyConstrainedBoxState> createState() => _MyState();
}

class _MyState extends State<MyConstrainedBoxState> {

  
  Widget build(BuildContext context) {


    return Scaffold(
      appBar: AppBar(
        title: const Text("MyConstrainedBoxState"),
      ),
      body:  Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              ConstrainedBox(
                constraints: BoxConstraints(
                  minWidth: double.infinity,
                  minHeight: 46,
                ),
                child: Container(
                  height: 59,
                  child: DecoratedBox(
                    decoration: BoxDecoration(color: Colors.blue),
                  ),
                ),
              ),
              Text("----------"),
              ConstrainedBox(
                constraints: BoxConstraints.tight(Size(60,80)),
                child: DecoratedBox(
                  decoration: BoxDecoration(color: Colors.blue),
                ),
              ),
              Text("----------"),
              SizedBox(
                width: 90,
                height: 90,
                child: DecoratedBox(
                  decoration: BoxDecoration(color: Colors.yellow),
                ),
              ),
              Text("----------"),
              ConstrainedBox(
                  constraints: BoxConstraints(minWidth: 90.0, minHeight: 20.0),
                  child: ConstrainedBox(
                    constraints: BoxConstraints(minWidth: 60.0, minHeight: 60.0),
                    child: DecoratedBox(
                      decoration: BoxDecoration(color: Colors.yellow),
                      child: UnconstrainedBox(
                        alignment: Alignment.topRight,
                        child:
                        SizedBox(
                          width: 80,
                          height: 20,
                          child: DecoratedBox(
                            decoration: BoxDecoration(color: Colors.red),
                          )
                        ),
                      ),
                    ),
                  )
              ),
              Text("----------"),
              ConstrainedBox(
                  constraints: BoxConstraints(minWidth: 60.0, minHeight: 60.0),  //父
                  child: ConstrainedBox(
                  constraints: BoxConstraints(minWidth: 5.0, minHeight: 80.0),//子
                    child: DecoratedBox(
                      decoration: BoxDecoration(color: Colors.orange),
                    ),
                  ),
              ),
              Text("------------"),
              ConstrainedBox(
                constraints: BoxConstraints.tightFor(width: 60,height: 60),// 最外围的约束是 宽 50  高 50
                child: ConstrainedBox(
                    constraints: const BoxConstraints.expand(), // 可以生成一个尽可能大的用以填充另一个容器的BoxConstraints
                    child: Container(
                      height: 59,  // 不起作用 ,以父容器的约束为准
                      width: 102,  // 不起作用 ,以父容器的约束为准
                      child: DecoratedBox(
                        decoration: BoxDecoration(color: Colors.red),
                      ),
                    ),
                ),
              ),
              Text("------------"),
              ConstrainedBox(
                  constraints: BoxConstraints(maxWidth: 90), // 创建一个宽度最大为90的约束
                  // height: 100,
                  child: AspectRatio( // 使用时 是根据父空间的宽高比进行设置的 ,如果父布局有具体宽高则 AspectRatio 失效
                    aspectRatio: 3,
                    child: Container(
                      color: Colors.pink,
                    ),
                  ),
              ),
            ],
          )
      ),
    );
  }


}