认真对待每时、每刻每一件事,把握当下、立即去做。

在 Flutter 中,布局确实完全通过组件(Widget)来实现,这与许多其他 UI 框架的设计理念不同。以下是 Flutter 布局系统的详细解析。

1. 布局组件的核心思想

  • 一切都是 Widget‌:无论是可见的按钮、文本,还是不可见的布局容器(如 Row、Column),均为 Widget。
  • 组合嵌套‌:通过父子组件的嵌套关系定义布局结构,例如将多个按钮包裹在 Row 中实现水平排列。
  • 响应式设计‌:布局组件自动根据父级约束和屏幕尺寸调整子组件的位置与大小。

2. 布局组件的工作原理

布局流程(约束传递):

  • 父级约束传递:父组件向子组件传递布局约束(如最大/最小宽高)。

  • 子级布局:子组件根据约束决定自身大小,例如:

    • Container:若未指定尺寸,则尽量填充父级允许的最大空间。
    • Text:根据内容自动计算所需尺寸。
  • 位置确定‌:父组件根据排列规则(如 Row 的主轴对齐)定位子组件。

3. 常见布局组件及用途

3.1 约束类容器

组件 作用 示例代码
BoxConstraints 描述约束信息 在布局过程中父级传递给子级的约束信息由 BoxConstraints 描述(最大、小宽高)
ConstrainedBox 约束组件 用于对子组件添加额外的约束
UnconstrainedBox 尝试移除父级约束 允许子控件在布局阶段忽略父级约束,但最终自身尺寸仍受父级约束限制。

特别解析1:

误以为 UnconstrainedBox 能完全突破父级约束‌:UnconstrainedBox 仅允许子控件在布局时忽略父级约束,但其 UnconstrainedBox 自身仍受父级约束限制。最终会将子组件的尺寸裁剪或压缩至父级允许范围内。

误以为溢出会被自动处理‌:若子控件尺寸超过 UnconstrainedBox 自身的约束,Flutter 默认会裁剪而非报错,但开发者模式下可能看到溢出警告。

若需要子控件完全突破父级约束,使用 OverflowBox 替代 UnconstrainedBox

‌3.2 布局容器/方式

方式 ‌‌组件 作用‌‌ 示例代码
基础容器布局 Container 通用容器,可设置尺寸、边距、背景色等 Container(width: 100, height: 50, color: Colors.blue)
线性布局 Row / Column 水平/垂直排列子组件(类似Android的 LinearLayout) Row(children: [Text("A"), Text("B")])
弹性布局 Flex 弹性布局允许子组件按照一定比例来分配父容器空间 Flutter 中的弹性布局主要通过FlexExpanded来配合实现
弹性扩伸 Expanded Expanded 只能作为 Flex 的孩子(否则会报错),它可以按比例“扩伸”Flex子组件所占用的空间、在Row/Column中占据剩余空间 Row(children: [Expanded(child: Text("占满宽度")), Icon(...)])
流式布局 Wrap / Flow Row 默认只有一行,如果超出屏幕不会折行。我们把超出屏幕显示范围会自动折行的布局称为流式布局
层叠布局 Stack 层叠布局和 Web 中的绝对定位、Android 中的 Frame 布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。 Stack(children: [Image(...), Positioned(child: Icon(...), bottom: 0)])
可滚动列表 ListView 可滚动的列表布局 ListView(children: [ListTile(...), ListTile(...)])

‌3.3 调整子组件大小

组件 作用 说明
SizedBox 固定尺寸的空白区域或强制子组件尺寸,实际上SizedBox只是ConstrainedBox的一个定制 本质也是约束类容器
ConstrainedBox 设置尺寸约束

‌3.4 调整子组件位置‌

组件 作用
Center 子组件居中
Align 按指定对齐方式(如右上角)定位子组件
Stack 层叠布局和 Web 中的绝对定位、Android 中的 Frame 布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。

特别解析2:

AlignStack/Positioned 都可以用于指定子元素相对于父元素的偏移,但它们还是有两个主要区别:

  • 定位参考系统不同;Stack/Positioned 定位的参考系可以是父容器矩形的四个顶点;而 Align 则需要先通过 alignment 参数来确定坐标原点,不同的 alignment 会对应不同原点,最终的偏移是需要通过 alignment 的转换公式来计算出。
  • Stack 可以有多个子元素,并且子元素可以堆叠,而 Align 只能有一个子元素,不存在堆叠。

4. 实际布局示例

‌4.1 垂直居中按钮

Center(
child: Container(
width: 200,
height: 50,
child: ElevatedButton(
onPressed: () {},
child: Text("点击我"),
),
),
)
  • 结构‌:CenterContainerElevatedButton
  • 效果‌:按钮在屏幕中央,宽 200、高 50。

‌4.2 复杂响应式布局

Column(
children: [
Expanded( // 占据剩余空间的70%
flex: 7,
child: Image.network("https://example.com/header.jpg"),
),
Padding(
padding: EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("标题"),
Icon(Icons.settings),
],
),
),
],
)
  • 结构‌:Column包含一个Expanded图片区域和一个带边距的Row标题栏。
  • 效果‌:图片占70%高度,标题栏左右分布。

‌5. 调试布局问题

  • Debug Paint‌:在代码中启用 debugPaintSizeEnabled = true,显示布局边框。
  • LayoutBuilder:LayoutBuilder 是一个可以访问父组件约束并基于这些约束构建子组件的组件。它允许开发者在构建时动态地获取父组件的布局信息,从而更好地控制子组件的布局。
  • Flutter Inspector‌:通过 IDE 插件查看 Widget 树和布局约束。
  • 错误提示‌:Flutter 引擎会直接指出溢出(如"RenderBox overflowed")等常见问题。

‌6. 最佳实践

Flutter 通过组件化布局实现了高度的灵活性和一致性。掌握 RowColumnExpanded 等核心组件的用法,结合约束传递机制,能够高效构建复杂且响应式的界面,以下是一些好的实践:

  • 优先使用内置布局组件‌:避免自定义复杂布局逻辑。
  • 合理拆分组件‌:将重复布局封装为自定义 Widget。
  • 利用 LayoutBuilder‌:在需要动态响应父级约束时使用。

》优秀博客:https://www.cnblogs.com/98kk/p/18626430

Flutter 布局核心思想的更多相关文章

  1. Flutter 布局控件完结篇

    本文对Flutter的29种布局控件进行了总结分类,讲解一些布局上的优化策略,以及面对具体的布局时,如何去选择控件. 1. 系列文章 Flutter 布局详解 Flutter 布局(一)- Conta ...

  2. Flutter 布局(三)- FittedBox、AspectRatio、ConstrainedBox详解

    本文主要介绍Flutter布局中的FittedBox.AspectRatio.ConstrainedBox,详细介绍了其布局行为以及使用场景,并对源码进行了分析. 1. FittedBox Scale ...

  3. Flutter 布局详解

    本文主要介绍了Flutter布局相关的内容,对相关知识点进行了梳理,并从实际例子触发,进一步讲解该如何去进行布局. 1. 简介 在介绍Flutter布局之前,我们得先了解Flutter中的一些布局相关 ...

  4. [深度学习] CNN的基础结构与核心思想

    1. 概述 卷积神经网络是一种特殊的深层的神经网络模型,它的特殊性体现在两个方面,一方面它的神经元间的连接是非全连接的, 另一方面同一层中某些神经元之间的连接的权重是共享的(即相同的).它的非全连接和 ...

  5. 《深入理解Spark:核心思想与源码分析》——SparkContext的初始化(叔篇)——TaskScheduler的启动

    <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...

  6. 《深入理解Spark:核心思想与源码分析》(前言及第1章)

    自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的<深入理解Spark:核心思想与源码分析>一书现在已经正式出版上市,目前亚马逊.京东.当当.天猫等网站均有销售 ...

  7. 《深入理解Spark:核心思想与源码分析》(第2章)

    <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...

  8. 《深入理解Spark:核心思想与源码分析》一书正式出版上市

    自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的<深入理解Spark:核心思想与源码分析>一书现在已经正式出版上市,目前亚马逊.京东.当当.天猫等网站均有销售 ...

  9. 《深入理解Spark:核心思想与源码分析》正式出版上市

    自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的<深入理解Spark:核心思想与源码分析>一书现在已经正式出版上市,目前亚马逊.京东.当当.天猫等网站均有销售 ...

  10. Hibernate核心思想—ORM机制(一)

    转:http://blog.csdn.net/wanghuan203/article/details/7566518 hibernate是一个采用ORM(Object/Relation Mapping ...

随机推荐

  1. 初见threejs

    threejs底层封装了强大的webGL技术,让开发者们可以开箱即用 (其实也并非开箱即用,还是挺麻烦的). 恰巧朋友遇到了些难题,借此契机,接触了下threejs. 官网是支持中文的,虽然翻译的很差 ...

  2. 如何在非vue组件中使用vuex

    简介 RT,有的时候想使用保存在vuex里面的东西 link https://laracasts.com/discuss/channels/vue/vuex-accessing-vuex-outsid ...

  3. 数学建模 研究生 word 模板

    简介 一篇好的模板可以让一起参赛的队友分工明确. 附上我准备的数据建模论文模板 word https://github.com/lishaohsuai/mathmatic_muban 欢迎提出不足点. ...

  4. PostgreSQL Docker部署指南

    1. Docker compose version: '3' services: postgresql: container_name: postgresql image: 'rapidfort/po ...

  5. POLIR-Laws-民法典: 第 2-4 章 自然人{民事能力:权利&行为/监护/宣告失踪死亡/个体工商户和农村承包经营户} + 法人{营利法人/非营利法人/特别法人} + 非法人组织 + 第五章: 民事权利

    POLIR-Laws-民法典: 第一章  基本规定: 人/组织: 自然人: 能力: 民事权利能力 和 民事行为能力 年龄 法人 营利法人 非营利法人 特别法人 非法人组织 物: 115..第一百一十五 ...

  6. SciTech-Mathmatics-Probability+Statistics-II-Population:Parameter Estimation + Samples:Statistics 总体的参数估计 和 样本统计量

    SciTech-Mathmatics-Probability+Statistics-Population:Region Parameter Estimation of Population + Sta ...

  7. SciTech-Health+Pharmacy-藻酸盐化学物 + 做牙模型的藻酸盐使用注意事项

    https://baike.baidu.com/item/藻酸盐/10984767 https://blog.kq88.com/index.php?s=/Headpage/Artshow/index/ ...

  8. SQL order by 大小比较盲注

    SQL order by 大小比较盲注 在做ctfshow web入门 的 web691时遇到了SQL order by 大小比较盲注问题.因为是第一次遇到,记录一下 在做题之前,我们先来探讨一下or ...

  9. 优化UGUI的ScrollRect

    http://qiankanglai.me/2015/08/15/LoopScrollRect/ https://github.com/qiankanglai/LoopScrollRect

  10. SQL自带时间数据

    SELECT NOW(),CURDATE(),CURTIME() 结果展示: