前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter | ConstrainedBox & UnconstrainedBox 组件

Flutter | ConstrainedBox & UnconstrainedBox 组件

作者头像
Flutter笔记
发布2019-12-16 15:09:15
9010
发布2019-12-16 15:09:15
举报
文章被收录于专栏:Flutter笔记Flutter笔记

0. 前言

在 Flutter 当中,我们如何控制组件的大小?套上一层 Container?SizeBox?还是一些别的技巧?

有没有同学遇到这种情况:在布局中,无论如何都控制不了一个组件的大小,烦的一批?

例如这段代码:

代码语言:javascript
复制
Widget build(BuildContext context) {
  return Scaffold(
    body: ListView.separated(itemBuilder: (context, index){
      return Container(
        height: 200,
        width: 200,
        color: Colors.amber,
      );
    }, itemCount: 10, separatorBuilder: (BuildContext context, int index) {
      return Container(height: 10,);
    },),
  );
}

我创建了一个ListView,每一个 item 是一个 200*200 的琥铂色(黄色)Container,讲道理,这个时候我们的脑海里就应该有这样的一个列表呈现。然而,当你运行的时候:

WTF??我 200*200 的大方块呢?怎么变成长方形了?

难道不应该是这样的吗?

好,带着这个问题,我们就来说今天的两个主角。

注意:这里并不打算深入讨论 Flutter 中约束的机制,只是为了讲解这两个控件

看本篇文章时我们只需要记住:child 尺寸大小是由父级 Widget 给出的约束来调整的。

其他的如果想要了解,可以看这篇处理边界约束 (Box constraints) 的问题[1]

1. ConstrainedBox

首先我们来说一下 ConstrainedBox,从名字上我们也能解读个大概:「约束盒」。

没错,就是约束盒,他是用来干嘛的?看一下官方文档:

A widget that imposes additional constraints on its child. For example, if you wanted child to have a minimum height of 50.0 logical pixels, you could use const BoxConstraints(minHeight: 50.0) as the constraints. 在其 child 上添加约束的 widget。 例如,如果你希望 child 最小高度为 50.0 像素,可以用 BoxConstraints(minHeight: 50.0) 来进行约束。

接下来再看一下他的构造函数:

代码语言:javascript
复制
ConstrainedBox({
  Key key,
  @required this.constraints,
  Widget child,
}) : assert(constraints != null),
assert(constraints.debugAssertIsValid()),
super(key: key, child: child);

可以看到,必要的参数有 constraints: BoxConstraints,这里也简单说一下约束:

约束是由最小宽度、最大宽度、最小高度、最大高度四个方面构成;尺寸大小则由特定的宽度和高度两个方面构成。

那我们再来看一下 BoxConstraints是怎么用的,它有6个构造函数,分别是:

1.BoxConstraints({double minWidth: 0.0, double maxWidth: double.infinity, double minHeight: 0.0, double maxHeight: double.infinity }):使用给定的约束来构建2.BoxConstraints.expand({double width, double height }):创建一个充满另一个约束的约束3.BoxConstraints.expand({double width, double height }):创建一个不能大于给定大小的约束4.BoxConstraints.tight(Size size):创建一个给定大小的约束5.BoxConstraints.tightFor({double width, double height }):同上6.BoxConstraints.tightForFinite({double width: double.infinity, double height: double.infinity }):创建给定大小的约束,除非他们是无限的

代码语言:javascript
复制
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: Container(
        height: 200,
        width: 200,
        color: Colors.amber,
      ),
    ),
  );
}

这是一个 200200 的Container,接下来定义一个 ConstrainedBox,并且把min宽高设定为 300\300:

代码语言:javascript
复制
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: ConstrainedBox(
        child: Container(
          height: 200,
          width: 200,
          color: Colors.amber,
        ), constraints: BoxConstraints(minHeight: 300, minWidth: 300),
      ),
    ),
  );
}

可以看到,这个时候 Container 的宽高完全是按照 ConstrainedBox 的约束来设定的。

2. UnconstrainedBox

该组件就厉害了,官方解释为:

A widget that imposes no constraints on its child, allowing it to render at its "natural" size. This allows a child to render at the size it would render if it were alone on an infinite canvas with no constraints. This container will then attempt to adopt the same size, within the limits of its own constraints. If it ends up with a different size, it will align the child based on alignment[2]. If the box cannot expand enough to accommodate the entire child, the child will be clipped. 对 child 不添加任何约束,允许他以 “自然”大小进行渲染。 这样一来,child就可以在没有约束的、无限的画布上进行渲染,然后此容器讲尝试在自身限制的范围内采用相同的大小,如果大小不相同,则根据 alignment 来对齐,如果child过大,则会裁剪 child。

在我们开头举的例子,为什么我设置 200*200 的Container默认是屏幕宽度的?

因为ListView这种类型的组件会根据滑动方向来设置约束。

例如垂直滑动,那么所有 item 的宽度都是默认 double.infinity,所以这个时候无论我们设置多少宽度都是无用的,

相反也一样。

所以,如果我们想自己设定 item 的宽度,就需要用到 UnconstrainedBox,不给child 设置约束。

3. 总结

这两个组件实际开发过程中使用的可能不是很多,但是了解一下肯定是要的,否则遇到类似的问题也很麻烦。

总结来讲,这些都属于 Flutter 约束中的知识点,只要有个了解就好了。

References

[1] 处理边界约束 (Box constraints) 的问题: https://flutter.cn/docs/development/ui/layout/box-constraints [2] alignment: https://api.flutter.dev/flutter/widgets/UnconstrainedBox/alignment.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Flutter笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0. 前言
  • 1. ConstrainedBox
  • 2. UnconstrainedBox
  • 3. 总结
    • References
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档